JVM-Java对象解析
Java对象解析
- java对象的内存布局:对象头 + 类型引用 + 实例数据 + 对齐填充

- 64位系统:一个对象最小 8+4+4= 16B
- 对象头:8字节(64bit)
- 类型引用:指针压缩开启时类型引用4字节,没开启时是8字节
- 实例数据:成员变量
- 对象填充:padding
- 32位系统:一个对象最小 4+4= 8B
- 对象头:4字节(32bit)
- 类型引用:类型引用4字节(32bit)
- 实例数据:成员变量
- 对象填充:padding
- 实例数据:父类中定义的实例变量会出现在子类实例变量之前
- 对齐填充(Padding):Java 虚拟机堆中对象之间的内存地址需要对齐至 8N(8 的倍数),如果对象占用不到 8N 个字节,那么就在对象后填充至 8N 个字节。
- 现在大部分CPU是64位,一次性可以处理8B的数据,8N对齐的内存可以减少CPU处理数据块的次数
- 对象与对象之间的内存对齐,可以使我们在 64 位系统中利用 32 位对象引用将内存寻址空间提升至 32G。既降低了对象引用的内存占用,又提升了内存寻址空间。
- 压缩指针:减少引用大小,增大寻址空间
- JVM默认开启-XX:+UseCompressedOops,使得64位的JVM中引用的是32位的,节省了引用一半的内存
- 同时由于JVM中对象大小是8N,即内存地址也是8N,正常情况下引用的值后三位都是0,既然后三位始终是 0,那么就没必要存储。可以将引用值右移3位,32位的引用所能表达的内存大小扩大到32G。当寻址的时候,JVM 将这 32 位的对象引用左移 3 位(后三位补 0)。
- 可以使用 -XX:ObjectAlignmentInBytes 修改对齐的倍数,可以增大寻址空间,但是会导致对齐字节增加,每个对象占用内存都变大。