jvm #
对象内存结构? #
对象由3个部分组成:
- 对象头
- 对象体
- 对齐填充
对象头包括:
- MarkWord:用于描述与对象相关的其他信息,如:是否加锁、GC标志位、MinorGC次数、对象默认的hashCode(通过 System.identityHashCode(Object) 方法可获取这个值)
- 类型指针
- 数组长度(可选)
对象体包括:
- 非静态属性(包括父类中的所有属性)
对象指针压缩?为什么不建议设置超过32GB的堆内存? #
bash
# 开启对象指针压缩
-XX:+UseCompressedOops
# 关闭对象指针压缩
-XX:-UseCompressedOops
# 开启类元数据指针压缩
-XX:+UseCompressedClassPointers
# 关闭类元数据指针压缩
-XX:+UseCompressedClassPointers
# 设置对象数据对齐字节数(默认值为8,范围8-256,必须为2的幂次)
-XX:ObjectAlignmentInBytes=8
在堆内存小于32GB的64位虚拟机中,默认开启对象指针压缩功能,指针压缩至32位,有利于较少内存消耗,降低GC频率。
原理:
在64位虚拟机中,对象数据经过8字节对齐后(可通过ObjectAlignmentInBytes选项修改对齐字节数),对象地址最后3位都是0,因此对于32位对象指针可通过左移3位访问至多32GB内存,原本需要8字节存储空间的对象地址可被压缩成4字节。若堆内存超过32GB,则指针不会被压缩。
被压缩的指针或数据:
- 静态变量(Class对象的属性指针)
- 成员变量(Object对象的属性指针)
- 对象数组的元素指针
- 数组长度
不被压缩的指针:
- 元数据区的类型指针
- 栈中的对象指针