jol工具的使用

JOL

简介

JOL(Java Object Layout)是用于分析 JVM 中对象布局方案的微型工具箱。这些工具大量使用 Unsafe、JVMTI 和 Serviceability Agent (SA) 来解码实际的 对象布局、占用空间和引用。这使得JOL比其他依赖堆转储、规范假设等的工具更准确。

使用

测试类

public class SimpleObject {
//primitive type
private byte b;
private boolean bl;
private short s;
private char c;
private int a;
private float f;
private double d;
private long l;
//reference type
private Object obj;
private Object [] objArray;
}

测试代码


/**
* 打印class布局
*/
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)