大战Java虚拟机【1】—— 内存
前言
要了解Java虚拟机首先要知道的基础就是内存。虚拟机存在的意义就是对内存进行管理,因为不用人为的去管理每个对象的内存,所以才让java使用起来那么方便,不用像c、c++那样去free。
运行时数据区
Java所管理的内存划分为不同的区域,每个区域都有自己的用处。
1、程序计数器PC
如果你学过汇编的话就很好理解,在计算机中指令是一条条执行的,PC就是记住当前执行到哪一行了。需要注意的是,每条线程都需要一个独立的PC,且互相之间不影响。
2、虚拟机栈
栈是一个在程序设计的时候很常见的一个数据结构,有一定计算机基础的话,你知道递归的实现其实就是利用栈,也知道递归的深度过大会导致栈溢出。而在Java虚拟机中栈是描述Java方法执行的内存模型,每个方法的执行就是虚拟机中一个入栈出栈的过程。
3、本地方法栈
这个栈和虚拟机栈一样,只是这个栈是一个VIP,只有native方法才会使用到这个栈,那什么是native方法呢?java方法可能会调用到非java-code的方法,如c的方法,这样的方法称为native方法。
4、堆
堆是最重要的一块也是比较复杂的一块区域,因为几乎所有的对象实例都在堆里分配内存。堆是垃圾回收的主要区域,因为很多用过之后没有用的对象都在这里了,它们所占用的内存都需要被回收。
5、方法区
用于存储已经被虚拟机加载的类信息、常量、静态变量等。看到它的功能基本可以想象到,它存放的东西基本上都属于那种不可改变而且一直存在的量,所以这个区域有时被称为“永久代”但是记住它们不一定都是永久的,这个区域也会被回收,只是相对来说没有像堆那样。
对象创建
内存是用来存放对象的,那么java是如何创建一个对象的呢?首先我们知道创建一个对象就是new出来,虚拟机在new之前还要做的事情是确定这个类是否已经被正确加载了。
接下来就是去分配内存了,当类被加载完成之后,我们就知道这个对象需要多大的内存了。如果内存是完整的,那就像切蛋糕一样切出一块来,如果内存是分散的,那就需要找一块足够大的切了。而内存是分散的还是完整的取决于垃圾回收的算法。
然后设置对象的参数,如这个对象是哪个类的实例,哈希码,GC分代年龄等。
最后再执行对象的init方法给每个需要的字段进行赋值,然后根据这个对象的构造方法进行初始化。
对象的访问
那么我们创建了一个对象之后,我们如何访问这个对象呢?这个时候就用到了我们的栈了,栈记录了一个对象的引用reference。这里有两种方式,第一种是这个引用数据保存了句柄数据然后堆中有一个句柄池其中记录了对象实例数据的指针,我们通过引用找到句柄池中的位置,再通过指针找到对象。第二种是指针访问,也就是直接储存了对象的地址。句柄的好处是,对象移动时reference不用改变,指针的好处是速度快。
感受虚拟机
我们运行两个程序来直观感受一下虚拟机到底做了什么事情
首先运行下面这个程序
import java.util.ArrayList;
import java.util.List; /**
* @author LinkinStar
*/
public class T {
static class A {
} public static List<A> list = new ArrayList<>(); public static void main(String[] args) {
while (true) {
list.add(new A());
}
}
}
需要注意的是,需要调整一下虚拟机的参数
Xms是JVM初始分配的堆内存
Xms是JVM最大允许分配的堆内存
然后运行就能看见异常Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
然后在相同的条件下我们运行第二个程序
/**
* @author LinkinStar
*/
public class T {
static class A {
} public static void main(String[] args) {
while (true) {
new A();
}
}
}
你会发现没有什么异常,然后你需要做的是,对比两个程序,看看这两个程序有什么不一样,这样的不一样为什么会导致这样的结果。理解了,你就知道java虚拟机到底在做什么事情了。
上面的测试是模拟了堆溢出的情况,还有方法区溢出,常量池溢出,栈溢出等,出现StackOverflowError或者OutOfMemoryError。
我们所要知道的是出现这样错误是什么样的原因导致的,以上就是在内存方向上虚拟机相关。
大战Java虚拟机【1】—— 内存的更多相关文章
- 如何写出让java虚拟机发生内存溢出异常OutOfMemoryError的代码
程序小白在写代码的过程中,经常会不经意间写出发生内存溢出异常的代码.很多时候这类异常如何产生的都傻傻弄不清楚,如果能故意写出让jvm发生内存溢出的代码,有时候看来也并非一件容易的事.最近通过学习< ...
- 深入理解java虚拟机【内存溢出实例】
通过简单的小例子程序,演示java虚拟机各部分内存溢出情况: (1).java堆溢出: Java堆用于存储实例对象,只要不断创建对象,并且保证GC Roots到对象之间有引用的可达,避免垃圾收集器回收 ...
- 从Java虚拟机的内存区域、垃圾收集器及内存分配原则谈Java的内存回收机制
一.引言: 在Java中我们只需要轻轻地new一下,就可以为实例化一个类,并分配对应的内存空间,而后似乎我们也可以不用去管它,Java自带垃圾回收器,到了对象死亡的时候垃圾回收器就会将死亡对象的内存回 ...
- Java虚拟机:内存模型详解
版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 我们都知道,当虚拟机执行Java代码的时候,首先要把字节码文件加载到内存,那么这些类的信息都存放在内存中的哪个区域呢?当我们创建一个对象实 ...
- 初识:java虚拟机的内存划分
什么是内存? 内存是计算机中的重要原件,临时存储区域,作用是运行程序.我们编写的程序是存放在硬盘中的,在硬盘中的程序是不会运行的,必须放进内存中才能运行,运行完毕后会清空内存.Java虚拟机要运行程序 ...
- java虚拟机的内存模型
一.为什么要了解java虚拟机的内存模型 java虚拟机作为java代码运行的平台,是java技术的基石.了解java虚拟机的内存模型也就变得十分必要.它能帮助我们更好的了解java代码的运行机制,更 ...
- java虚拟机的内存机制
我们都知道,java程序的跨平台性离不开java虚拟机,虚拟机隔绝了底层操作系统,使得java程序可以直接运行在虚拟机之上.所以,对java的学习,离不开对java虚拟机的学习与了解.下面简单整理下j ...
- Java虚拟机的内存管理
众所周知,Java程序员写的代码是没有办法控制Java对象的内存释放的,完全有JVM暗箱操作. 虽然程序员把内存的释放的任务都交给了Java虚拟机,但是并不代表Java程序就不存在内存泄漏. 反而,某 ...
- 1 - JVM随笔分类(java虚拟机的内存区域分配(一个不断记录和推翻以及再记录的一个过程))
java虚拟机的内存区域分配 在JVM运行时,类加载器ClassLoader在加载到类的字节码后,交由jvm的执行引擎处理, 执行过程中需要空间来存储数据(类似于Cpu及主存),此时的这段空间的分 ...
- JAVA虚拟机:内存各个区介绍
概述:java应用程序由java虚拟机自动管理程序执行期间内存管理. 优势:1.不再需要程序员去为使用的内存在程序中手动编写释放内存代码. 2.由虚拟机管理内存不容易出现内存泄漏和内存溢出的问题. 缺 ...
随机推荐
- time-based基于google key生成6位验证码(google authenticator)
由于公司服务器启用了双因子认证,登录时需要再次输入谷歌身份验证器生成的验证码.而生成验证码是基于固定的算法的,以当前时间为基础,基于每个人的google key去生成一个6位的验证码.也就是说,只要是 ...
- Microsoft Graph: Developer Blog
https://developer.microsoft.com/en-us/graph/blogs/announcing-30-days-of-microsoft-graph-blog-series/ ...
- angular.isUndefined()
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- SQL插入数据--数据中的某一列来自本表中的数据
背景: 项目初期使用的配置库和业务库两种数据库并行,所有配置数据位于配置库,所有业务数据根据不同省份位于不同数据库.由于使用省份越来越多,各省的配置数据也越来越多导致配置库的数据量过于庞大,各省共用一 ...
- thinkphp 找数据库某个字段为空的数据,PHP 数据调取 空数据
$arr['dingwei'] = array('EXP','is null');
- Burp Suite Pro 教程
1.Burp Suite Pro2.0.11破解版-2018.11.06更新 说明基地址 来源:http://ximcx.cn/post-110.html 启动;如果是用的burp2.0,把下面的代码 ...
- git 服务器搭建与运用
环境:CentOS 6 为了不影响后面的安装 安装依赖库 yum install curl-devel expat-devel gettext-devel openssl-devel zlib-dev ...
- java 的基本数据类型及转换
数据类型精度: byte 8 位short 16 位int 32 位long 64 位float 32 位double 64 位char 16 位 boolean 占几位要看 jvm 的具体实现, 虽 ...
- 麒麟子Cocos Creator实用技巧
大家好,我是麒麟子, 开源棋牌<幼麟棋牌-四川麻将>(泄漏版叫 <达达麻将>)作者,成都幼麟科技创始人. 自09年进入游戏行业以来,不知不觉已经度过了十个春秋. 曾经我也血气方 ...
- idea Empty git --version output:解决
在使用idea下的git时候发现报错 但看了一下我的git-bas位置确实没有错啊,也可以启动 后来google了才下发现原来idea的这个地方不用引用的git-bash.exe的路径,而是git.e ...