JOL
简介
JOL(Java Object Layout)是用于分析 JVM 中对象布局方案的微型工具箱。这些工具大量使用 Unsafe、JVMTI 和 Serviceability Agent (SA) 来解码实际的 对象布局、占用空间和引用。这使得JOL比其他依赖堆转储、规范假设等的工具更准确。
使用
测试类
public class SimpleObject { private byte b; private boolean bl; private short s; private char c; private int a; private float f; private double d; private long l; private Object obj; private Object [] objArray; }
|
测试代码
public void testPrintClassLayout(){ ClassLayout classLayout = ClassLayout.parseClass(SimpleObject.class); System.out.println(classLayout.toPrintable()); }
public void testPrintObjectLayout(){ SimpleObject obj = new SimpleObject(); System.out.println(ClassLayout.parseInstance(obj).toPrintable()); }
|
关闭指针压缩
VM参数:-XX:-UseCompressedOops
Class Layout
SimpleObject object internals: OFF SZ TYPE DESCRIPTION VALUE 0 8 (object header: mark) N/A 8 8 (object header: class) N/A 16 8 double SimpleObject.d N/A 24 8 long SimpleObject.l N/A 32 4 int SimpleObject.a N/A 36 4 float SimpleObject.f N/A 40 2 short SimpleObject.s N/A 42 2 char SimpleObject.c N/A 44 1 byte SimpleObject.b N/A 45 1 boolean SimpleObject.bl N/A 46 2 (alignment/padding gap) 48 8 java.lang.Object SimpleObject.obj N/A 56 8 java.lang.Object[] SimpleObject.objArray N/A Instance size: 64 bytes Space losses: 2 bytes internal + 0 bytes external = 2 bytes total
|
Object Layout
SimpleObject object internals: OFF SZ TYPE DESCRIPTION VALUE 0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0) 8 8 (object header: class) 0x000000001c123380 16 8 double SimpleObject.d 0.0 24 8 long SimpleObject.l 0 32 4 int SimpleObject.a 0 36 4 float SimpleObject.f 0.0 40 2 short SimpleObject.s 0 42 2 char SimpleObject.c 44 1 byte SimpleObject.b 0 45 1 boolean SimpleObject.bl false 46 2 (alignment/padding gap) 48 8 java.lang.Object SimpleObject.obj null 56 8 java.lang.Object[] SimpleObject.objArray null Instance size: 64 bytes Space losses: 2 bytes internal + 0 bytes external = 2 bytes total
|
开启指针压缩
默认是开启的
VM参数:-XX:+UseCompressedOops
uid:8个字节
timpstamp:8个字节
Map每个Node大小
4+8+8+4
hash(4) + key(8) + value(8) +next(4)
每个用户占用16个字节
Class Layout
SimpleObject object internals: OFF SZ TYPE DESCRIPTION VALUE 0 8 (object header: mark) N/A 8 4 (object header: class) N/A 12 4 int SimpleObject.a N/A 16 8 double SimpleObject.d N/A 24 8 long SimpleObject.l N/A 32 4 float SimpleObject.f N/A 36 2 short SimpleObject.s N/A 38 2 char SimpleObject.c N/A 40 1 byte SimpleObject.b N/A 41 1 boolean SimpleObject.bl N/A 42 2 (alignment/padding gap) 44 4 java.lang.Object SimpleObject.obj N/A 48 4 java.lang.Object[] SimpleObject.objArray N/A 52 4 (object alignment gap) Instance size: 56 bytes Space losses: 2 bytes internal + 4 bytes external = 6 bytes total
|
Object Layout
SimpleObject object internals: OFF SZ TYPE DESCRIPTION VALUE 0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0) 8 4 (object header: class) 0xf800c105 12 4 int SimpleObject.a 0 16 8 double SimpleObject.d 0.0 24 8 long SimpleObject.l 0 32 4 float SimpleObject.f 0.0 36 2 short SimpleObject.s 0 38 2 char SimpleObject.c 40 1 byte SimpleObject.b 0 41 1 boolean SimpleObject.bl false 42 2 (alignment/padding gap) 44 4 java.lang.Object SimpleObject.obj null 48 4 java.lang.Object[] SimpleObject.objArray null 52 4 (object alignment gap) Instance size: 56 bytes Space losses: 2 bytes internal + 4 bytes external = 6 bytes total
|
指针压缩对结果的影响
以下都是基于64bit
操作系统的测试结果
|
开启指针压缩 |
关闭指针压缩 |
对象头 |
12byte |
16byte |
引用类型 |
4byte |
8byte |
其他
对象的大小是8
的倍数,如果不是8
的倍数,jvm在创建对象分配内存时会填充字节
用以对齐
JUC lock与synchronized 差异
线程状态
// Thread State
// ReentrantLock.lock -> java.lang.Thread.State: WAITING (parking)
waiting on condition
// synchronized -> java.lang.Thread.State: BLOCKED (on object monitor) waiting for monitor entry
// get lock on sleep -> java.lang.Thread.State: TIMED_WAITING (sleeping)