一、對象布局
1、對象頭
1)存儲對象自身的運行時數(shù)據(jù)
hash碼、GC分代年齡、鎖狀態(tài)標志、線程持有的鎖、偏向線程ID、偏向時間戳等。占位32/64位虛擬機分別占32/64個比特,官方稱"Mark Word"
2)類型指針
指向?qū)ο蟮脑獢?shù)據(jù),如果是數(shù)組,還會存儲數(shù)組長度。
2、實例數(shù)據(jù)
3、對齊填充
要求對象是8的整數(shù)倍,對象頭已經(jīng)是8位的整數(shù)倍,只填充實例數(shù)據(jù)即可。
二、Object o = new Object()內(nèi)存占用情況
占用16個字節(jié)
對象頭12個字節(jié),對齊填充4個字節(jié),共16個
使用ClassLayout進行查看內(nèi)存布局
maven
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.9</version>
</dependency>
Object o = new Object();
System.out.println(ClassLayout.parseInstance(o).toPrintable());
輸出結(jié)果
java.lang.Object object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1)
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
三、查看鎖的標記位

1652873201(1).png
鎖升級過程
1、無鎖狀態(tài)(001)
2、無鎖 ->偏向鎖 : 給普通對象加個synchronized,初始就是偏向鎖(101)
3、偏向鎖 -> 自旋鎖(輕量級鎖 00),JVM發(fā)現(xiàn)有第二個線程去競爭該鎖,變成自旋鎖(輕量級鎖 00)
4、自旋鎖 -> 重量級鎖 : 當JVM發(fā)現(xiàn)線程競爭激烈的時候,就把自旋鎖升級為重量級鎖。判斷標準有兩個,一個是自旋超過10次,另一個是wait的線程個數(shù)超過CPU的一半。
1、未鎖定=>輕量級鎖定
public static void main(String[] args) {
Object o = new Object();
System.out.println(ClassLayout.parseInstance(o).toPrintable());
synchronized (o){
System.out.println(ClassLayout.parseInstance(o).toPrintable());
}
}

1652873487(1).png
2、輕量級鎖=>重量級鎖
@SneakyThrows
public static void main(String[] args) {
Object o = new Object();
System.out.println("new ---" + ClassLayout.parseInstance(o).toPrintable());
new Thread(() -> {
synchronized (o) {
System.out.println("Thread 1 -- " + ClassLayout.parseInstance(o).toPrintable());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
Thread.sleep(1000);
new Thread(() -> {
synchronized (o) {
System.out.println("Thread 2 -- " + ClassLayout.parseInstance(o).toPrintable());
}
}).start();
}

image.png