深入理解JVM(二)

深入理解JVM(二)

第2章 Java内存区和内存溢出异常

1.Java运行时数据区

image

1.1程序计数器 PCR

a)通过改变PCR的数值来选取下一条需要执行的字节码指令。
b)一个内核只会执行一条线程中的指令。所以单核多线程是SB
c)PCR区域是线程私有的。

1.2 Java虚拟机栈

a)他有一个局部变量表存放编译期已知的各种基本数据类型,其中long和double两个胖子要占两个变量空间(slot)。这部分内存在编译期间就分配完成。
b)他也是线程私有的。

1.3 本地方法栈 Native Method Stack

人如其名,就这样。

1.4 Java堆

a)堆是所有线程共享的,占内存区域是最大的。
b)Java堆可以是处于物理上不连续的内存,逻辑内存连续就OK。
c)被GC的主要区域。

1.5 方法区

a)线程共享,存储类信息、常量、静态变量

==32位系统内存只能是4GB, 因为内存大小受到处理器寻址空间的限制==

b)运行时也可以将新的常量放入常量池,比如String类的intern()方法。

2.JVM上对象的创建

a)JVM遇到new,首先去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。
b)给新生对象分配内存,一种是“指针碰撞Bump the Pointer”,另一种方法是“空闲列表Free List”,使用哪一种方法取决于GC是否带有压缩整理功能。
c)保证分配内存是线程安全的两种,一是采用CAS+失败重试,二是本地线程分配缓冲TLAB(就是每个线程都先分一块自己家的地)

3.对象的内存布局

3.1 对象在内存中的存储布局分成3块:对象头、实例数据、对齐填充。
3.1.1对象头分为存储对象自身的运行时数据(Mark Word)和类型指针。
3.1.2实例数据的存储顺序是由JVM的分配策略参数和字段在Java源码中定义的顺序决定。
3.1.3 JVM要求对象的起始地址是8字节的整数倍,所以有对齐填充。

4.对象的访问定位

分为句柄和直接指针两种。后者节省了一次指针定位的时间开销,被主流JVM使用;前者也有人用,其他高级语言会用。

猜你喜欢

转载自blog.csdn.net/u014744127/article/details/80159869