分析工具
可通过JOL工具进行分析
依赖
testImplementation 'org.openjdk.jol:jol-core:0.16'
示例代码
import org.junit.jupiter.api.Test;
import org.openjdk.jol.info.ClassLayout;
public class ObjectLayoutTest {
@Test
void testLayout(){
System.out.println( ClassLayout.parseInstance(new ObjectA()).toPrintable() );
System.out.println("***********************************************************");
System.out.println( ClassLayout.parseInstance(new ObjectA[]{new ObjectA()}).toPrintable() );
}
public static class ObjectA{
private long a;
}
}
结果
com.xxx.sprbegin.ObjectLayoutTest$ObjectA object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0)
8 4 (object header: class) 0xf801ef34
12 4 (alignment/padding gap)
16 8 long ObjectA.a 0
Instance size: 24 bytes
Space losses: 4 bytes internal + 0 bytes external = 4 bytes total
***********************************************************
[Lcom.xxx.sprbegin.ObjectLayoutTest$ObjectA; object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0)
8 4 (object header: class) 0xf802ef3a
12 4 (array length) 1
12 4 (alignment/padding gap)
16 4 com.wywtime.sprbegin.ObjectLayoutTest$ObjectA ObjectLayoutTest$ObjectA;.<elements> N/A
20 4 (object alignment gap)
Instance size: 24 bytes
Space losses: 4 bytes internal + 4 bytes external = 8 bytes total
布局分析
JAVA对象的内存布局大体分三块内容:
对象头
其主要包括两部分数据:Mark Word、Class对象指针。数组的话会多一个四字节的array length。 Class对象指针默认开启指针压缩,占四个字节。
实例数据
用于存放该对象的实例数据,如果是对象,存在是引用地址。
内存填充
64位的HotSpot要求Java对象地址按8字节对齐,即每个对象所占内存的字节数必须是8字节的整数倍。因此Java对象需要通过内存填充来满足对齐要求
示例图
MarkWord
参考文章
https://zhuanlan.zhihu.com/p/151856103