《深入理解java虚拟机》 第二章
1.运行数据区域
1.1线程私有
1.1.1 程序计数器
字节码解释器通过程序计数器里的数值来寻找下一条要执行的指令
执行native方法无程序计数器值
无OOM
1.1.2 java虚拟机栈
每一个方法运行时都会建立一个栈帧,栈帧用来存储局部变量表(基本类型,对象引用),操作数栈等信息,每一个方法执行到推出对应在虚拟机栈中入栈出栈。
1.1.3 本地方法栈
类似虚拟机栈,执行native方法
1.2 线程共享
1.2.1 java堆
存放实例对象
1.2.2 方法区
用于存储类信息,常量,静态变量
该区域垃圾回收:1.类型卸载 2.常量池的回收
1.2.3运行时常量池(方法区)
1.3 直接内存
与运行时内存无关
引入了一种基于通道(Channel)与缓冲区(Buffer)的I/O 方式,它可以使用native 函数库直接分配堆外内存,然后通脱一个存储在Java堆中的DirectByteBuffer 对象作为这块内存的引用进行操作
2.对象
2.1 对象的创建
1.虚拟机遇到new指令是,会去检查这个指令是否能定位到一个类的符号引用,如果定位到,会去检查这个类是否已经被加载解析初始化过,如没有,需进行类加载过程
2.加载完成以后,会去为对象分配内存。两种方法:1,”指针碰撞” java内存区域是规整的,用过的在一边,没有过的在一边,有一个指针作为分界点,分配内存的时候直接让此指针在未用过的一边进行内存分配。2。”空闲列表” 虚拟机维护了一个列表,用来记录哪些空间是空闲的,分配的时候查这个表找到空闲的空间足够的内存进行分配。
分配内存还涉及同步的问题,解决方法:1.CAS 2.本地线程分配缓存,每个线程有自己独立的TLAB,分配的时候优先在自己的TLAB分配,不够了才需要同步
内存分配完成,将分配的内存空间初始化为0值
2.2 对象的组成 内存布局
2.2.1 对象头
1.对象头一部分存储对象自身的运行时数据(称为Mark Word),如哈希码,GC分代年龄,锁状态标志,线程持有的锁,偏向锁ID,偏向时间戳;
2.另一部分是类型指针,即对象指向它的类元数据的指针.虚拟机通过这个指针来确定这个对象是哪个类的实例
2.2.2 实例数据
对象真正存储的有效信息,程序代码中所定义的各种字段内容
2.2.3 对齐填充
2.3 对象的访问
Java程序通过栈上的reference数据来操作堆上的具体对象