Java是一个面向对象的语言,在Java中可以使用new关键字来产生一个对象,但这个对象到底是什么?下面详解@mikechen
Java对象组成
在HotSpot虚拟机中,真实的Java对象是分成三个部分:
1.对象头
对象头:用于存储对象自身运行时数据,包括哈希值(hashcode)、类型、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。
2.实例数据
实例数据:用于存放类的数据信息,父类的信息,对象字段属性信息
3.对齐填充
对象的填充字节 :在JVM中,要求对象占用内存的大小应该是8bit的倍数,这个信息是用来补齐8bit的
Java对象头
对象头是Java中对象都具有的属性,是jvm在编译和运行阶段读取的信息。
对象头主要包括两部分:
- Mark Word
- 类型指针
其中最复杂的是MarkWord,MarkWord用于存储对象自身的运行时数据, 如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等等。
标记字段(Mark Word)
MarkWord用于存储对象自身的运行时数据, 如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等等。
MarkWord占用空间大小根据JVM决定,为JVM的一个字大小,也就是32位JVM中Mark Word占用4个字节,64位JVM中占用8个字节64位。
为了节省空间,Mark Word是以非固定的数据结构来存储,具体数据结构如下:
1)在32位的环境中,Java头存储的信息如下:
2)在64位的环境中,Java头存储的信息如下:
3)参数介绍,如下:
「锁标志位(lock):」区分锁状态,这个参数总共占2bit,可以表示四种状态,但是上面图中,锁状态有五种,可以看出,无锁态 和 偏向锁都用 01 表示。那怎么区分无锁态跟偏向锁?这时引入 是否偏向锁 参数。
「是否偏向锁(biased_lock):」是否偏向锁,这个参数占 1bit,0表示 不是偏向锁,1表示 是偏向锁
「分代年龄(age):」表示java对象被GC的次数,每次GC的时候,如果对象在Survivor区复制一下,年龄增加1。当对象达到设定的阀值时,将会晋升到老年代。这个参数占 4bit,也就是最大值是 2^4 – 1 = 15。这是JVM参数XX:MaxTenuringThreshold选项最大值为15的原因。默认情况下并行GC的年龄阀值为15,并发GC的年龄阀值为6。
「hashCode:」对象的hashCode,使用方法System.identityHashCode()计算,采用延迟计算,计算后会把结果写到该对象头中。当对象被锁定时,该值会移动到Monitor中。
「线程ID:」在偏向模式中,当某个线程持有该对象,则该对象头的 线程ID位置存储的是这个线程的ID。这样在后面的操作中,就不需要再进行获取锁的动作
「epoch:」偏向锁时间戳,用于在CAS锁操作过程中,偏向性标识,表示更偏向哪个锁
「ptr_to_lock_record:」在轻量级锁的状态下,指向栈中锁记录的指针。当锁获取是无竞争时,JVM使用原子操作而不是OS互斥。这种技术称为轻量级锁定。在轻量级锁定的情况下,JVM通过CAS操作在对象头中设置指向锁记录的指针
「ptr_to_heavyweight_monitor:」在重量级锁的状态下,指向管程Montior的指针。如果两个不同的线程同时在同一个对象上竞争,则必须将轻量级锁定升级到Monitor心管理等待的线程。在重量级锁定的情况下,JVM设置ptr_to_heavyweight_monitor指向Montior。
类型指针(Klass Pointer)
这个字段存储对象的类元数据的指针,JVM通过这个指针来确定这个对象是哪个类的实例,占用JVM一个 字大小,即32bit JVM占4字节,64bit JVM占8字节。
Java对象头总结
通过对象在内存中的布局分析,我们可以明白一些问题的底层解释,比如:
- 如何计算java对象在内存中占用空间大小:可以从java对象头、实体数据、填充数据三部分来计算;
- JVM如何获取对象的GC年龄:在对象头Mark Word有一个分代年龄(age)来记录对象的GC年龄;
- 为啥最大GC15次后,对象就会被移动老年代:因为分代年龄(age)字段占用空间大小是4bit,也就是15,这个32bit还是64bit都是一样的。
另外我们发现对象头中有很多锁状态相关的字段,这个主要跟synchronized锁有着,涉及锁升级,锁优化等,这个可以参考:Synchronized的底层实现原理详解
陈睿mikechen
10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。
关注「mikechen」公众号,获取更多技术干货!
后台回复【面试】即可获取《史上最全阿里Java面试题总结》,后台回复【架构】,即可获取《阿里架构师进阶专题全部合集》