JVM調優之——禁用偏向鎖優化

JVM調優之——禁用偏向鎖優化

JVM參數

-XX:-UseBiasedLocking //關閉偏向鎖(默認打開)

或者

-XX:+UseHeavyMonitors //設置重量級鎖

使用條件

STW的開銷>用戶態與內核態切換的開銷

如果你想了解原理,請往下看

首先我們來複習幾個概念

用戶態與內核態

操作系統中的程序,一般都是在用戶態下運行的。當程序需要藉助操作系統來完成一些自己無法完成的操作時,便會從用戶態切換到內核態,如果頻繁切換,這樣的開銷還是很大的

重量級鎖

其實現原理是通過操作系統調用MutexLock來保證競態資源的互斥,所以會產生用戶態與內核態的切換

CAS

比較實際內存值與預期內存值,相同則更新內存值,否則什麼都不做(這是Java調用的一串cpu指令,不具體討論)

更新失敗的原因就是各個線程cpu緩存的可見性問題

偏向鎖

偏向鎖只有在出現競爭的時候纔會釋放。在一個線程嘗試獲取偏向鎖時,JVM會對比該線程ID與鎖對象頭中的線程ID,相同則說明該線程已經持有該鎖,直接執行同步方法;不同則通過CAS操作改變對象頭中的線程ID。可見與重量級鎖相比,偏向鎖降低了用戶態與內核態切換的開銷

雖然偏向鎖起到了優化作用,但是也有弊端

在併發程度相對較大的程序中,CAS改變對象頭線程ID有可能失敗,這時會導致撤銷偏向鎖,並嘗試將偏向鎖升級爲輕量級鎖。偏向鎖的撤銷操作會在全局安全點(safepoint)暫停當前持有該鎖的線程,如果此時該線程沒有執行同步方法,則該線程釋放鎖,同時其他線程重新競爭對象鎖,否則將鎖升級。在這裏頻繁地撤銷偏向鎖會導致線程長時間暫停,也是很大的開銷

撤銷偏向鎖會讓持鎖線程暫停,是因爲當CAS改變對象頭線程ID失敗後,需要根據持鎖線程狀態判斷,是將鎖變爲無鎖狀態還是升級爲輕量級鎖。如果不暫停持鎖線程,可能判斷線程狀態的時候還是運行狀態,決定將鎖對象升級爲偏向鎖;但升級之前線程又結束了,需要釋放鎖,這樣會產生衝突鎖頭狀態的衝突

所以當線程暫停的時間大於偏向鎖帶來的用戶態與內核態切換節省下來的時間時,我們需要禁用偏向鎖優化

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章