java文件头_对java文件头的解析
java對象保存在內(nèi)存中時有3個部分
1.對象頭
2.實例數(shù)據(jù)
3.對齊填充字節(jié)
一. 對象頭
? java的對象頭有3部分組成:
? 1.Mark Word
? 2.指向類的指針
? 3.數(shù)組長度(如果是數(shù)組對象的話才有)
1.Mark Word
Mark Word 存儲的內(nèi)容 32bit 中如下所示:
其中無鎖和偏向鎖的鎖標志位都是01 只是用前一位來表示是無鎖還是偏向鎖
JDK1.6后的版本在處理同步鎖時存在鎖升級的概念,JVM對于同步鎖的處理是從偏向鎖開始的 處理方式從偏向鎖升級到輕量鎖 最終升級為重量級鎖.
Ps :鎖只可單向升級 不可降級
JVM一般是這樣使用鎖和Mark Word的:
JVM一般是這樣使用鎖和Mark Word的:
1,當沒有被當成鎖時,這就是一個普通的對象,Mark Word記錄對象的HashCode,鎖標志位是01,是否偏向鎖那一位是0。
2,當對象被當做同步鎖并有一個線程A搶到了鎖時,鎖標志位還是01,但是否偏向鎖那一位改成1,前23bit記錄搶到鎖的線程id,表示進入偏向鎖狀態(tài)。
3,當線程A再次試圖來獲得鎖時,JVM發(fā)現(xiàn)同步鎖對象的標志位是01,是否偏向鎖是1,也就是偏向狀態(tài),Mark Word中記錄的線程id就是線程A自己的id,表示線程A已經(jīng)獲得了這個偏向鎖,可以執(zhí)行同步鎖的代碼。
4,當線程B試圖獲得這個鎖時,JVM發(fā)現(xiàn)同步鎖處于偏向狀態(tài),但是Mark Word中的線程id記錄的不是B,那么線程B會先用CAS操作試圖獲得鎖,這里的獲得鎖操作是有可能成功的,因為線程A一般不會自動釋放偏向鎖。如果搶鎖成功,就把Mark Word里的線程id改為線程B的id,代表線程B獲得了這個偏向鎖,可以執(zhí)行同步鎖代碼。如果搶鎖失敗,則繼續(xù)執(zhí)行步驟5。
5,偏向鎖狀態(tài)搶鎖失敗,代表當前鎖有一定的競爭,偏向鎖將升級為輕量級鎖。JVM會在當前線程的線程棧中開辟一塊單獨的空間,里面保存指向?qū)ο箧iMark Word的指針,同時在對象鎖Mark Word中保存指向這片空間的指針。上述兩個保存操作都是CAS操作,如果保存成功,代表線程搶到了同步鎖,就把Mark Word中的鎖標志位改成00,可以執(zhí)行同步鎖代碼。如果保存失敗,表示搶鎖失敗,競爭太激烈,繼續(xù)執(zhí)行步驟6。
6,輕量級鎖搶鎖失敗,JVM會使用自旋鎖,自旋鎖不是一個鎖狀態(tài),只是代表不斷的重試,嘗試搶鎖。從JDK1.7開始,自旋鎖默認啟用,自旋次數(shù)由JVM決定。如果搶鎖成功則執(zhí)行同步鎖代碼,如果失敗則繼續(xù)執(zhí)行步驟7。
7,自旋鎖重試之后如果搶鎖依然失敗,同步鎖會升級至重量級鎖,鎖標志位改為10。在這個狀態(tài)下,未搶到鎖的線程都會被阻塞。
2,指向類的指針
該指針在32位JVM中的長度是32bit,在64位JVM中長度是64bit。
Java對象的類數(shù)據(jù)保存在方法區(qū)。
3,數(shù)組長度
只有數(shù)組對象保存了這部分數(shù)據(jù)。
該數(shù)據(jù)在32位和64位JVM中長度都是32bit。
二,實例數(shù)據(jù)
對象的實例數(shù)據(jù)就是在java代碼中能看到的屬性和他們的值。
三,對齊填充字節(jié)
因為JVM要求java的對象占的內(nèi)存大小應(yīng)該是8bit的倍數(shù),所以后面有幾個字節(jié)用于把對象的大小補齊至8bit的倍數(shù),沒有特別的功能。
本文由博客群發(fā)一文多發(fā)等運營工具平臺 OpenWrite 發(fā)布
總結(jié)
以上是生活随笔為你收集整理的java文件头_对java文件头的解析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 测试岗位 mysql 面试题_一套实用的
- 下一篇: java 删除文件失败_java 文件