基于前面我们介绍的JVM对象内存布局,可以知道,一个对象占用的内存大小受操作系统和是否开启压缩指针的影响。为了方便推算对象的占用内存大小,帅旋画了一般比较直观的图:
下面假设是在64位操作系统,并且开启了压缩指针的情况下分析一个对象占用内存大小。
一个Object对象
1
| Object obj = new Object();
|
对象头:8 + 4 = 12
对齐填充:填充到8的整数倍,为16。
我们可以使用jol-core提供的工具类验证下:
1 2 3 4 5
| <dependency> <groupId>org.openjdk.jol</groupId> <artifactId>jol-core</artifactId> <version>0.10</version> </dependency>
|
代码:
1
| System.out.println(ClassLayout.parseInstance(new Object()).toPrintable());
|
执行结果:
1 2 3 4 5 6 7 8
| java.lang.Object object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 4 (object header) 05 00 00 00 (00000101 00000000 00000000 00000000) (5) 4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0) 8 4 (object header) e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243) 12 4 (loss due to the next object alignment) Instance size: 16 bytes Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
|
可以发现,占用16个字节,并且使用了4个字节的对齐填充。
一个简单的Java对象
要是我们在对象里面存储自己的私房钱,那么这个对象会占用多少内存呢?
对象如下:
1 2 3 4 5
| public class ItzhaiInfo {
private Object 私房钱;
}
|
执行以下代码:
1
| System.out.println(ClassLayout.parseInstance(new ItzhaiInfo()).toPrintable());
|
结果如下:
1 2 3 4 5 6 7 8
| com.itzhai.jucdemo.sync.ItzhaiInfo object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 4 (object header) 05 00 00 00 (00000101 00000000 00000000 00000000) (5) 4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0) 8 4 (object header) 81 c1 00 f8 (10000001 11000001 00000000 11111000) (-134168191) 12 4 java.lang.Object ItzhaiInfo.私房钱 null Instance size: 16 bytes Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
|
可以发现,还是16字节,只不过这不需要对齐填充了,多了4个字节的对象指针。