“这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战”
引言
咱们接着上回说道,虚拟机做完一切之后,以为自己搞定了一切,实际上才刚刚开始,后续还有很多工作要做,我们今天借着一杯茶的工夫来说一下。
init方法
new指令执行后,紧跟着的就是init方法,也就是构造方法,调用完这个方法,一个我们真正意愿上的对象才算被造出来。
//todo没有肝源码(还没看)
对象的内存布局
对象头(header)
对象头包含两部分:存储对象自身的运行数据和对象的指针。这个好理解,因为我们需要存储操作的数据并且还要知道它的类型。
运行数据(mark word)
运行数据包含:哈希code、GC分带年龄、锁的状态标志、线程持有锁、偏向线程id、偏向时间戳等,对象要存储的数据很多(就像你出门,大包小包都要带,很累),那咋整呢?我们能不能动态分配空间呢(不是很重要的东西就现买),hotspot是这么做的,稍微扩展一丢丢,给对象定义状态,根据对象的状态来动态复用,具体状态的存储内容如下:
注:图片来源于:《深入理解java虚拟机》
类型指针
类型指针是对象指向该类型元数据的指针,就是你是谁家的孩子,你就得指向谁,那是必须这么玩嘛,也不是,这个我们以后在讨论,需要注意的是,如果对象是个数组,那就需要在对象头中记录数组的长度。
实例数据(instance data)
对象存储的真正有效的信息在这部分,有啥呢:你在代码里写的所有的字段(父子类的都算),相同宽度的放在一起。
对齐部分(padding)
占位符,hotspot要求任何对象的大小必须是8字节的倍数,如果没有满足,就填充补齐。
题外话
还是要努力,哪怕进步慢一点。