运行时数据区
线程共享区域:
1.方法区
2.堆
线程隔离区:
1.虚拟机栈
2.本地方法栈
3.程序计数器
1.程序计数器
该区域是一块较少的内存空间,此内存区域是唯一一个在Java虚拟机规范中没有规定任何OOM情况的区域。
如果执行的是Java程序,这该计数器记录的是正在执行的虚拟机字节码的指令地址,如果为Native方法,则计数器的值为空(Undefined)
2.Java虚拟机栈
1.生命周期与线程相同
2.每个方法都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。
3.每个方法从调用直至执行完的过程,对应着一个栈帧在虚拟机中从入栈到出栈的过程
4.当线程请求的栈深度大于虚拟机所允许的深度则抛出StackOverflowError异常,
当无法申请到足够内存时,则抛出OOM异常
3.本地方法栈
1.与虚拟机栈相似,虚拟机栈为Java方法服务,而本地方法栈为native方法服务
2.抛出异常与虚拟机栈相同
4.Java堆
1.在虚拟机启动时创建,用于存放对象实例
2.内存回收:基本采用分代收集算法,划分为新生代和老年代
划分为新生代和老年代:
Eden空间、from survivor空间,to survivor空间等
5.方法区
1.存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
2.又称永久代
6.运行时常量池
1.此为方法区的一部分,用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池存放
2.String类的intern()方法可在运行期间将新的常量放入池中
对象的内存布局
在HotSpot虚拟机中,对象的内存布局分为3块区域:
1.对象头(Header)
2.实例数据(Instance Data)
3.对齐填充
对象头Mark Word
存储内容 | 标志位 | 状态 |
---|---|---|
对象哈希码、对象分代年龄 | 01 | 未锁定 |
指向锁记录的指针 | 00 | 轻量级锁定 |
指向重量级锁的指针 | 10 | 膨胀(重量级锁定) |
空、不需要记录信息 | 11 | GC标记 |
偏向线程ID,偏向时间戳,对象分代年龄 | 01 | 可偏向 |