本文内容总结自周志明先生所编著的《深入理解Java虚拟机-JVM高级特性与最佳实践》此书的经典不必多说。本节内容是对象的内存布局。
在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头、实例数据、对齐填充(Padding)。在32位虚拟机中对象头的大小是8个字节,在64位虚拟机中对象头的大小是16个字节, 如果开启压缩的话,对象头的大小是12个字节。对象头包含两部分的信息,一部分是对象自身的运行时数据,包含哈希码、GC分代年龄、锁状态信息、线程持有的锁、偏向线程ID、偏向时间戳等。另一部分的信息是类型指针。虚拟机可以通过这个来确定这个对象是哪个类的实例(但不是所有的虚拟机都必须在对象数据上保留类型指针,因为对象访问方式有使用句柄和直接指针两种方式)。如果对象是数据,则对象头中还有一部分数据用来记录数据长度。关于对象头信息的一些例子:
对象头的长度
Java对象头的存储结构(32位虚拟机)
对象头的状态变化(32位虚拟机)
64位虚拟机
实例数据部分是对象真正存储的有效信息,也是在程序代码中所定义的各种类型的字段内容。对象中的字段存储顺序和在代码中写的顺序是不同的。在HotSpot虚拟机中,默认的分配策略是long/double、int/float、short/char、byte/boolean、oops(对象引用)。这些字段所占用的内存大小为:long / double - 8 bytes,int / float
- 4 bytes,short / char - 2 bytes,byte/boolean - 1 bytes,reference type - 4 or 8 bytes。long/double要求8字节对齐。相同字宽的字段总是被分配到一起。
对齐填充不是必然存放的,它仅仅起着占位符的作用。HotSpot虚拟机的自动内存管理系统要求对象起始地址必须是8字节的整数倍,也就是对象的大小必须是8字节的整数倍。
内存布局大家可以参考这一篇文章:http://blog.csdn.net/lqp276/article/details/52190503。