今天看了京東T10技術專家王新棟的直播,首先很感謝大佬的分享,分享的主要方向是服務邊界劃分,但是我聽到了除了技術以外的聲音,就是對程式碼負責,開發過程中允許有技術債務,但是技術債務一定要償還,如果不償還技術債務,就不是技術上的問題了,而是道德上的問題,同時也在跟隨王老師堅持學習,讓學習成為一種習慣,希望更多喜歡技術的人,讓程式設計除了作為生存的基本技能之外,更多的是作為生活的一部分,一種習慣,我們結伴而行
關於物件頭,我覺得還是單獨拿出來記錄,因為線上程安全的實現中,跟物件頭有直接關係,方便我們定位這塊知識
物件記憶體佈局
物件記憶體佈局,分為物件頭(MarkWord+型別指標)、例項資料、對其填充,對其填充只針對例項資料,物件頭在設計的時候就是8位元組對齊的,如果是陣列還有一個數組長度
MarkWord在32位作業系統佔4位元組(32bit),在64位作業系統未開啟指標壓縮的情況下佔8位元組(64bit),開啟指標壓縮的情況佔4位元組(32bit),MarkWord的作用就是記錄物件鎖狀態,配合GC、存放物件hash;Mark Word包含物件hash、分代年齡、鎖狀態標識,執行緒持有的鎖、偏向執行緒ID、偏向時間戳等,不同狀態下儲存內容也不同,目的是為了節省記憶體空間,下圖為hotspot的markOop物件頭描述
鎖狀態 |
32bit |
||||
25bit |
4bit |
1bit |
2bit |
||
23bit |
2bit |
偏向模式 |
標誌位 |
||
無鎖 |
物件hashCode |
分代年齡 |
0 |
01 |
|
輕量級鎖 |
指向呼叫棧中鎖記錄的指標 |
00 |
|||
重量級鎖(鎖膨脹) |
指向重量級鎖的指標(重量級鎖的ObjecrMonitor類包含物件HashCode) |
10 |
|||
GC標記 |
空 |
11 |
|||
可偏向模式(可設定) |
執行緒ID |
Epoch(偏向時間戳) |
分代年齡 |
1 |
01 |
型別指標指向方法區的物件型別元資料,型別指標在32位作業系統佔4位元組(32bit),在64位作業系統未開啟指標壓縮的情況下佔8位元組(64bit),開啟指標壓縮的情況佔4位元組(32bit),jvm就是根據型別指標確定是哪個類的物件,棧中引用定位物件例項的方式有2種,一種是指標,一種是控制代碼池,指標的方式引用儲存的是物件的地址,控制代碼池的方式,引用儲存的是物件的控制代碼地址,控制代碼中儲存物件地址,控制代碼池的好處是物件被移動的時候,只需要改變控制代碼對物件的引用,如垃圾回收,物件記憶體位置變更的情況
陣列長度,如果不是陣列物件,佔0位元組,如果是陣列物件佔4個位元組,儲存的是陣列的長度,陣列長度使用的是int型別,最大個數位2的32次方-1
例項資料,儲存的是物件的屬性,包含基本資料型別和引用資料型別,引用資料型別未開啟指標壓縮的情況佔8位元組,開啟指標壓縮的情況佔4個位元組
ideal檢視物件頭,引入maven依賴
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.9</version>
</dependency>
列印物件頭
1:Mark Word
2:型別指標
3:物件屬性
4:對其填充
5:陣列物件多一個數組長度