激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務器之家 - 編程語言 - Java教程 - JAVA對象分析之偏向鎖、輕量級鎖、重量級鎖升級過程

JAVA對象分析之偏向鎖、輕量級鎖、重量級鎖升級過程

2021-08-03 11:08等不到的口琴 Java教程

這篇文章主要介紹了JAVA對象分析之偏向鎖、輕量級鎖、重量級鎖升級過程,又對這方面感興趣的同學可以跟著一起研究下

在HotSpot虛擬機里,對象在堆內存中的存儲布局可以劃分為三個部分:

對象頭(Header)

實例數據(Instance Data)

對齊填充(Padding)。

對象頭

HotSpot虛擬機(后面沒有說明的話默認是這個虛擬機)對象頭包括三部分:

  1. Mark Word
  2. 指向類的指針
  3. 數組長度(只有數組對象才有)

對象頭之Mark Word

Mark Word記錄了對象和鎖有關的信息,當這個對象被synchronized關鍵字當成同步鎖時,圍繞這個鎖的一系列操作都和Mark Word有關。

Mark Word在32位JVM中的長度是32bit,在64位JVM中長度是64bit。

Mark Word在不同的鎖狀態下存儲的內容不同,在32位JVM中是這么存的:

JAVA對象分析之偏向鎖、輕量級鎖、重量級鎖升級過程

一共32位,兩位用來記錄鎖的信息,1位用來記錄是否是偏向鎖,如果偏向鎖是1的話,那么會分配23位來記錄偏向的線程id,當計算過Hash后,意味著會分配25bit來記錄HashCode,那么久沒有空間用來記錄偏向鎖的線程ID了,所以計算過HashCode后就沒法再進入偏向鎖。如果進入輕量級鎖或者重量級鎖,意味著會用30bit指向指針,那么此時對象頭中就只有兩種信息,鎖標志、指向鎖的指針。

其中無鎖和偏向鎖的鎖標志位都是01,只是在前面的1bit區分了這是無鎖狀態還是偏向鎖狀態。

JDK1.6以后的版本在處理同步鎖時存在鎖升級的概念,JVM對于同步鎖的處理是從偏向鎖開始的,隨著競爭越來越激烈,處理方式從偏向鎖升級到輕量級鎖,最終升級到重量級鎖。

結合Mark Word分析鎖升級的流程:

1,當沒有被當成鎖時,這就是一個普通的對象,Mark Word記錄對象的HashCode,鎖標志位是01,是否偏向鎖那一位是0(0則false , 1 則true)。

2,當對象被當做同步鎖并有一個線程A搶到了鎖時,鎖標志位還是01,但是否偏向鎖那一位改成1,前23bit記錄搶到鎖的線程id,表示進入偏向鎖狀態。

3,當線程A再次試圖來獲得鎖時,JVM發現同步鎖對象的標志位是01,是否偏向鎖是1,也就是偏向狀態,Mark Word中記錄的線程id就是線程A自己的id,表示線程A已經獲得了這個偏向鎖,可以執行同步鎖的代碼。

4,當線程B試圖獲得這個鎖時,JVM發現同步鎖處于偏向狀態,但是Mark Word中的線程id記錄的不是B,那么線程B會先用CAS操作試圖獲得鎖,這里的獲得鎖操作是有可能成功的,因為線程A一般不會自動釋放偏向鎖。如果搶鎖成功,就把Mark Word里的線程id改為線程B的id,代表線程B獲得了這個偏向鎖,可以執行同步鎖代碼。如果搶鎖失敗,則繼續執行步驟5。

5,偏向鎖狀態搶鎖失敗,代表當前鎖有一定的競爭,偏向鎖將升級為輕量級鎖。JVM會在當前線程的線程棧中開辟一塊單獨的空間,里面保存指向對象鎖Mark Word的副本,同時在對象鎖Mark Word中保存指向這片空間的指針。上述兩個保存操作都是CAS操作,如果保存成功,代表線程搶到了同步鎖,就把Mark Word中的鎖標志位改成00,可以執行同步鎖代碼。如果保存失敗,表示搶鎖失敗,競爭太激烈,繼續執行步驟6。

6,輕量級鎖搶鎖失敗,JVM會使用自旋鎖,自旋鎖不是一個鎖狀態,只是代表不斷的重試,嘗試搶鎖。從JDK1.7開始,自旋鎖默認啟用,自旋次數由JVM決定。如果搶鎖成功則執行同步鎖代碼,如果失敗則繼續執行步驟7。

7,自旋鎖重試之后如果搶鎖依然失敗,同步鎖會升級至重量級鎖,鎖標志位改為10。在這個狀態下,未搶到鎖的線程都會被阻塞。

對象頭之指向類的指針

該指針在32位JVM中的長度是32bit,在64位JVM中長度是64bit。

Java對象的類數據保存在方法區。 并不是所有的虛擬機實現都必須在對象數據上保留類型指針,換句話說,查找對象的元數據信息并不一定要經過對象本身。

對象頭之數組長度

如果對象是一個Java數組,那在對象頭中還必須有一塊用于記錄數組長度的數據,因為虛擬機可以通過普通Java對象的元數據信息確定Java對象的大小,但是如果數組的長度是不確定的,將無法通過元數據中的信息推斷出數組的大小。

只有數組對象保存了這部分數據, 該數據在32位和64位JVM中長度都是32bit。

實例數據

實例數據部分是對象真正存儲的有效信息,即我們在程序代碼里面所定義的各種類型的字段內容,無論是從父類繼承下來的,還是在子類中定義的字段都必須記錄起來。這部分的存儲順序會受到虛擬機分配策略參數(-XX:FieldsAllocationStyle參數)和字段在Java源碼中定義順序的影響。HotSpot虛擬機默認的分配順序為longs/doubles、ints、shorts/chars、bytes/booleans、oops(OrdinaryObject Pointers,OOPs),從以上默認的分配策略中可以看到,相同寬度的字段總是被分配到一起存放,在滿足這個前提條件的情況下,在父類中定義的變量會出現在子類之前。如果HotSpot虛擬機的+XX:CompactFields參數值為true(默認就為true),那子類之中較窄的變量也允許插入父類變量的空隙之中,以節省出一點點空間。

對齊填充

這并不是必然存在的,也沒有特別的含義,它僅僅起著占位符的作用。由于HotSpot虛擬機的自動內存管理系統要求對象起始地址必須是8字節的整數倍,換句話說就是任何對象的大小都必須是8字節的整數倍。對象頭部分已經被精心設計成正好是8字節的倍數(1倍或者2倍),因此,如果對象實例數據部分沒有對齊的話,就需要通過對齊填充來補全。

到此這篇關于JAVA對象分析之偏向鎖、輕量級鎖、重量級鎖升級過程的文章就介紹到這了,更多相關偏向鎖、輕量級鎖、重量級鎖升級過程內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://www.cnblogs.com/Courage129/p/14364988.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 成年人小视频在线观看 | 黄色av电影在线播放 | 日本免费一区二区三区四区 | 成人午夜一区二区 | www.三区 | 久久丝袜脚交足黄网站免费 | 黄色网络免费看 | hd性videos意大利复古 | 噜噜噜躁狠狠躁狠狠精品视频 | 香蕉国产9 | 日本成人一二三区 | 国产高潮失禁喷水爽到抽搐视频 | 国产高清成人久久 | 视频一区 在线 | 奇米影视奇奇米色狠狠色777 | 136福利视频 | 久久蜜桃香蕉精品一区二区三区 | 国产一级免费电影 | 欧美成人免费电影 | 婷婷中文字幕一区二区三区 | 黄色aaa视频 | 国产精品一区二区免费在线观看 | 黄色的视频在线观看 | 羞羞的视频免费观看 | 欧美a区 | 国产1区视频 | 成人免费网站在线观看视频 | 久久久电影电视剧免费看 | h视频免费在线观看 | 精品偷拍久久 | 亚洲天堂中文字幕在线观看 | 女人一级一级毛片 | 国产在线导航 | 色3344| 欧美日韩中文字幕在线 | 一级在线视频 | 国产精品啪一品二区三区粉嫩 | 一级毛片免费一级 | 国产免费黄网 | 亚洲午夜视频 | 爱福利视频 |