jvm中使用到的鎖優化技術主要包括:
自旋鎖和適應性自旋鎖、鎖消除、鎖粗化、輕量級鎖、偏向鎖
1.自旋鎖和自適應鎖:當乙個執行緒執行耗時小的一小段同步**,另乙個執行緒可以不放棄處理器的執行時間,等待看看持有鎖的執行緒是否很快就會釋放鎖,為了使執行緒等待,可以讓執行緒執行忙迴圈(自旋),自適應自旋是指自旋的時間不在確定了,而是由前一次在同乙個鎖上的自旋時間及鎖的擁有者的狀態決定,以及總共在該鎖自旋成功的次數等因素智慧型化決定
2.鎖消除:例如如下**,即時編譯後會消除所有同步
public string concatstring(string s1,string s2,string s3)
3.鎖粗化:例如如下**,就可以將兩段合為一段
synchronized(f)
i=0;
synchronized(f)
4.輕量級鎖:首先要明白物件頭由兩部分組成,一部分用於存物件的hash碼、gc代,另一部分用於儲存指向方法區物件型別資料的指標,如果是陣列還會有額外的部分用於儲存陣列長度,hotspot物件頭mark word中標誌位01代表未加鎖、00代表輕量級鎖,10代表重量級鎖,第乙個執行緒進入該同步塊,會將物件頭複製到棧中lock record,並使用cas嘗試將物件的mark word更新為指向lock record的指標,並將mark word的鎖標誌位改為00,表明此物件處於輕量級鎖定狀態,如果這個cas更新過失敗,虛擬機會首先檢查物件的mark word是否指向當前執行緒的棧幀,如果當前執行緒已經擁有了鎖就可以執行,如果不是說明兩個執行緒共同爭搶乙個鎖,鎖就會膨脹為重量級鎖10,後面等待鎖的執行緒就要進入阻塞狀態,私以為這些執行緒執行完畢,物件頭恢復10將會重新進行一輪輕量級鎖,雖然課本上指明重量級鎖不能恢復為輕量級鎖,但是私以為是分階段的,否則,大部分是單執行緒執行的同步塊,因為偶爾一次衝突就變成重量級鎖優化度智慧型性不高,當執行緒執行完要解鎖輕量級鎖時,同樣使用cas進行,如果物件的mark word仍指向著執行緒的鎖記錄,那就用cas操作把物件當前的mark word和執行緒中複製的displaced mark word換回來,如果替換成功,同步完成,如果失敗,說明其他執行緒嘗試著獲取該鎖,那麼原來執行緒在釋放鎖的同時喚醒被掛起的執行緒,如果存在鎖競爭,除了互斥量的開銷還有cas的開銷,輕量級鎖會比重量級鎖更慢。
5.偏向鎖:乙個執行緒第一次進入同步塊時,設定對該執行緒偏向,同時使用cas把獲取到這個鎖的執行緒的id記錄在物件的mark word中,如果成功,持有偏向鎖的執行緒在下一次進入該鎖相關的同步塊時(當下一次該執行緒進入該物件鎖同時中間沒有其他執行緒擾亂),虛擬機器都可以不進行任何同步操作(locking、unlocking等),另外乙個執行緒訪問時,撤銷偏向(物件未鎖定)恢復到未鎖定或者輕量級鎖定(物件已鎖定)的狀態,接下來和輕量級鎖一樣。
淺入理解JVM虛擬機器
1.類載入過程 驗證 準備 解析 初始化 驗證階段 判斷.class檔案符合規範標準 準備階段 給類以及靜態變數分配記憶體並給初始值 0 解析階段 維護哥哥字段,方法類的記憶體指標或偏移量 初始化階段 變數賦值 真實的值 執行 什麼時候乙個類會進行初始化階段?1.new乙個例項化物件時 2.包含ma...
深入理解Java虛擬機器 JVM記憶體洩漏
jvm記憶體洩漏 記憶體洩漏就是存在一些物件沒有被 這些物件是可達的,但是這些物件是無用的,那麼這些物件就存在記憶體洩漏,即不會被gc 但是卻占用記憶體。記憶體溢位主要分為以下幾種 1.靜態集合類引起記憶體洩漏 像hashmap vector等的使用最容易出現記憶體洩露,這些靜態變數的生命週期和應用...
深入理解Java虛擬機器
1.class檔案是一組以8位位元組為基礎單位的二進位製流,各個資料專案嚴格按照順序緊湊地排列在class檔案中,中間沒有新增任何分隔符,這使得整個class檔案中儲存的內容幾乎全部是程式執行的必要資料,沒有空隙存在。當遇上占用8位位元組以上的資料時,按照高位在前的方式分割成若干個8位進行儲存 大端...