深入理解JAVA虚拟机阅读笔记——JAVA内存区域
一、Java内存区域
1.程序计数器
线程私有。
当前线程所执行的字节码的行号指示器。由于JAVA是多线程的,因此每个线程都独立的程序计数器。
异常:没有规定任何OutOfMemeryError情况的区域。
2. Java虚拟机栈
线程私有。
描述Java方法的内存模型——栈帧(局部变量表、操作数栈、动态链接、方法出口)。每个方法从调用到执行完成,对应一个栈帧入栈到出栈的过程。
异常:*Error和OutOfMemoryError异常
3.本地方法栈
线程私有。
本地方法栈为虚拟机用到的Native方法服务。
异常:*Error和OutOfMemoryError异常
4.Java堆
线程共享。
所有的对象实例以及数组都要在堆行分配,因此是垃圾回收器管理的主要区域,也称为"GC堆"。
从垃圾回收角度,又将堆分为“新生代”和“老年代”或者“Eden”、“From Survivor”、“To Survivor”。
从多线程角度,可将堆划分出多个线程私有的分配缓冲区(TLAB)。
异常:OutOfMemoryError异常
5.方法区
线程共享。
主要为类服务,存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
运行时常量池是方法区的一个组成部分,用以存放编译期生成的各种字面量和符号引用。
异常:OutOfMemoryError异常
二、对象的创建过程
-
虚拟机遇到一个new指令,首先检查指令的参数能否在常量池中定位到一个类的符号引用;
-
检查这个引用代表的类是否已被加载、解析、初始化过;
-
如果没有,则进入到类的初始化过程;
-
如果有,则类加载检查通过后,为新生对象在堆中分配内存。分配内存的方法可以是“指针碰撞”,也可以是“空闲列表”等。考虑多线程情况,先在TLAB中分配内存,TLAB用完时,才用到同步锁定;
-
将分配的内存空间都初始化为0;
-
在对象的对象头中进行必要的设置(哪个类?、如果找到类的元数据、哈希码、GC分代年龄等);
-
虚拟机完成初始化,开始用户自定义初始化;
三、对象的访问定位
访问定位的方式有两种:
1.使用句柄
2. 直接指针
上一篇: python跨文件使用全局变量的实现
推荐阅读
-
深入理解java虚拟机系列初篇(一):为什么要学习JVM?
-
《深入理解Java虚拟机》-----第13章 线程安全与锁优化
-
《深入理解Java虚拟机》-----第10章 程序编译与代码优化-早期(编译期)优化
-
读书笔记:深入理解java虚拟机(二)创建对象的时候需要访问哪几块内存
-
读书笔记:深入理解java虚拟机(一)虚拟机的运行时的数据区域
-
《深入理解Java虚拟机》-----第12章 Java内存模型与线程
-
深入理解Java虚拟机(第三版)-14. 线程安全与锁优化
-
深入理解Java虚拟机(第三版)-13.Java内存模型与线程
-
《深入理解Java虚拟机》(三)垃圾收集器与内存分配策略
-
Java内存区域与虚拟机类加载机制