使用JOL查看java对象内存结构
JOL(Java Object Layout) 工具包可以展示java对象在jvm中的结构信息,用来进行内存分析。是由openjdk提供的小工具包。git地址https://github.com/openjdk/jol。因此下面的测试基于hotspot虚拟机环境下。
添加依赖
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.16</version>
</dependency>
打印JVM基本信息
System.out.println(VM.current().details());
/**
输出内容:
# Running 64-bit HotSpot VM.
# Using compressed oop with 0-bit shift.
# Using compressed klass with 3-bit shift.
# Objects are 8 bytes aligned.
# Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
# Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
**/
Objects are 8 bytes aligned 表示对象大小是8bytes的倍数,不足会进行padding填充。
field size 代表各种属性类型所占字节大小:依次是[reference(对象引用类型),boolean,byte,short,char,int,float,long,double]所占的字节大小。
打印class
System.out.println(ClassLayout.parseClass(User.class).toPrintable());
/**
输出:
User object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) N/A
8 4 (object header: class) N/A
12 4 int User.id N/A
16 4 java.lang.String User.name N/A
20 4 (object alignment gap)
Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
**/
输出8个字节长度的mark work.会包含hashcode,锁状态和垃圾回收等信息。
4个字节长度的kclass信息。共12个长度头。
再往下就是对象的field信息。可以看到有一个4个byte的int型和4个byte的String类型。这里String为什么是4个byte呢?因为是引用类型。
object alignment gap是4,会进行填充。
打印实例对象
User user = new User();
user.setName("test");
user.setId(1);
System.out.println(ClassLayout.parseInstance(user).toPrintable());
/**
输出:
object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000005 (biasable; age: 0)
8 4 (object header: class) 0x20013287
12 4 int User.id 1
16 4 java.lang.String User.name (object)
20 4 (object alignment gap)
Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
**/
大小和上面的class一样,只不过value有值了。