Java虚拟机(二) - 对象 创建流程、内存分配

一、对象的创建流程
从虚拟机的视角,对象创建完成了,对于Java来说,对象创建才刚刚开始, 方法还没有执行,所有字段都还是零
虚拟机遇到一条new指令
检查指令参数是否能在常量池中定位到一个类的符号引用,并检查这个符号引用代表的类是否已被加载解析和初始化过
为新生对象分配内存
执行类加载过程
将分配到的内存空间都初始化为零值,不包括对象头
虚拟机对对象进行必要的设置,例如对象是哪个类的实例,如何找到类的元数据信息,对象的哈希码等
执行init方法,把对象按照程序员的意愿进行初始化
二、对象的内存布局

在HotSpot(sun jdk和openJDK中所带的虚拟机,是目前使用最广的虚拟机)虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header)、实例数据(Instance Data)和对齐信息(Padding)。

1、对象头

对象头包含两部分信息

第一部分(Mark Word)
用于存储对象自身的运行时数据,如哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。
Mark Word数据的长度在32位和64位的虚拟机(未开启压缩指针)中分别为32bit和64bit

  • GC分代年龄
    HotSpot使用分代垃圾回收机制,被分为三个代:年轻代(Young Generation)、年老代(Old Generation)和持久代(Permanent Generation)。
    (1)年轻代:所有新生成的对象首先都是放在年轻代的。年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象。
    (2)年老代:在年轻代中经历了N次垃圾回收后仍然存活的对象,就会被放到年老代中。因此,可以认为年老代中存放的
    都是一些生命周期较长的对象。
    (3)持久代:用于存放静态文件,如今Java类、方法等。

注意:Java8去除了持久代

  • 锁状态标志
    Mark Word的最后2bit是锁状态标志位,用来标记当前对象的状态。对象的所处的状态决定了Mark Word存储的内容,如下表所示:
状态标志位存储内容
未锁定01对象哈希码、对象分代年龄
轻量级锁定00指向锁记录的指针
膨胀(重量级锁定)10执行重量级锁定的指针
GC标记11空(不需要记录信息)
可偏向01偏向线程ID、偏向时间戳、对象分代年龄

第二部分(类型指针)
对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。

2、实例数据
实例数据是对象真正存储的有效信息,也是在程序代码中所定义的各种类型的字段内容。

3、对齐填充
不必然存在,也没有特别的含义,仅仅起了占位符的作用。HotSpot VM 规定对象的大小必须是8字节的整数倍,当对象实例数据没有对齐时,需要对齐填充补全

三、对象的内存分配

Java自动内存管理最终可归结为自动化的解决了两个问题:给对象分配内存及回收分配给对象的内存。

  1. 对象优先在Eden(新生代Eden区)分配
    如果Eden没有足够的空间分配,虚拟机将发起一次Minor GC
  2. 大对象直接进入老年代
    大对象是指需要大量连续内存空间的Java对象,最典型的大对象就是很长的字符串以及数组。
  3. 长期存活的对象将进入老年代
    每个对象有个年龄计数器。如果对象在Eden出生并经过第一次Minor GC后仍然存活,并且能被Survivor容纳的话,将被移动到Survivor空间中,并且对象年龄设为1.对象在Survivor每熬过一次Minor GC,对象年龄加1。当对象到达15(默认15,通过-XX:MaxTenuringThreshold设置)的时候,将被晋升到老年代。
  4. 并不是所有对象年龄必须到达MaxTenuringThreshold才能晋升老年代
    如果Survivor空间中,相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象可以直接进入老年代。
四、其他
  • Minor GC (新生代GC)
    发生在新生代的垃圾收集动作,Minor GC非常频繁,回收速度快。
  • Major GC / Full GC (老年代GC)
    发生在老年代的GC,出现Major GC,经常会伴随至少一次的Minor GC(不绝对)。Major GC的速度一般比Minor GC 慢10倍以上。
  • Eden 、 Survivor
    新生代分为一个Eden区,两个Survivor区。Eden和Survivor的空间大小比例是8:1

[1] 周志明 · 深入理解Java虚拟机 :机械工业出版社
[2] GC分代相关概念摘自 https://www.cnblogs.com/weiguo21/p/5195460.html
[3] 锁状态标志相关摘自 https://blog.csdn.net/kirito_j/article/details/79201213

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值