Java普通对象在内存中的构成
一、对象头(markword,64位系统上占用8个字节,共64位,32位系统则32位)

以上是Java对象处于5种不同状态时,Mark Word中64个位的表现形式,上面每一行代表对象处于某种状态时的样子。如图可以看出,当对象已经计算过identity_hashcode了,它就无法进入偏向锁状态,因为空间不够存放hashcode。另一个方面,当对象已经是偏向锁的状态,就没有足够的空间放入hashcode,因此只能移动到管程monitor中。
对象头包含以下几种属性:
-
lock,锁状态标记,2位
-
biased_lock:对象是否启用偏向锁标记,只占1个二进制位。为1时表示对象启用偏向锁,为0时表示对象没有偏向锁。lock和biased_lock共同表示对象处于什么锁状态。
-
age:4位的Java对象年龄。__由于age只有4位,所以最大值为15,这就是-XX:MaxTenuringThreshold选项最大值为15的原因。GC信息。
-
identity_hashcode:31位的对象标识hashCode,采用延迟加载技术。调用方法System.identityHashCode()计算,并会将结果写到该对象头中。当对象加锁后(偏向、轻量级、重量级),MarkWord的字节没有足够的空间保存 hashCode,因此该值会移动到管程Monitor中。
-
thread:持有偏向锁的线程ID。
-
epoch:偏向锁的时间戳。
-
ptr_to_lock_record:轻量级锁状态下,指向栈中锁记录的指针。
-
ptr_to_heavyweight_monitor:重量级锁状态下,指向对象监视器Monitor的指针。
关于对象头和锁之间的转换,网上大神总结

2.类指针(classPointer,占用4或8个字节)
-XX:+UseCompressedClassPointers 为4字节 不开启为8字节
3.实例数据
引用类型:-XX:+UseCompressedOops 为4字节 不开启为8字节 Oops Ordinary Object Pointers(string等)
4.Padding对齐,8的倍数
数组对象
1、对象头:markword 8
2、ClassPointer指针同上
3、数组长度:4字节
4、数组数据
5、对齐 8的倍数
实例
private static class P {
//8字节 _markword
//4字节 _oop指针
int id; //4字节
String name; //4字节
int age; //4字节
byte b1; //1字节
byte b2; //1字节
Object o; //4字节
byte b3; //1字节
}
常用对象(-XX:+UseCompressedClassPointers)
1、new Object(8+4+0+4)
2、new int
网友评论