一、目錄
1.啟蒙知識(shí)預(yù)熱:CAS原理+JVM對(duì)象頭內(nèi)存存儲(chǔ)結(jié)構(gòu)
2.JVM中鎖優(yōu)化:鎖粗化、鎖消除、偏向鎖、輕量級(jí)鎖、自旋鎖。
3.總結(jié):偏向鎖、輕量級(jí)鎖,重量級(jí)鎖的優(yōu)缺點(diǎn)。
二、啟蒙知識(shí)預(yù)熱
開啟本文之前先介紹2個(gè)概念
2.1.cas操作
為了提高性能,JVM很多操作都依賴CAS實(shí)現(xiàn),一種樂(lè)觀鎖的實(shí)現(xiàn)。本文鎖優(yōu)化中用到了CAS,故有必要先分析一下CAS的實(shí)現(xiàn)。
CAS:Compare and Swap。
JNI來(lái)完成CPU指令的操作:
unsafe.compareAndSwapInt(this, valueOffset, expect, update);
CAS有3個(gè)操作數(shù),內(nèi)存值V,舊的預(yù)期值A(chǔ),要修改的新值B。當(dāng)且僅當(dāng)預(yù)期值A(chǔ)和內(nèi)存值V相同時(shí),將內(nèi)存值V修改為B,否則什么都不做。
打開源碼:openjdk\hotspot\src\oscpu\windowsx86\vm\ atomicwindowsx86.inline.hpp,如下圖:0
os::is_MP() 這個(gè)是runtime/os.hpp,實(shí)際就是返回是否多處理器,源碼如下:
如上面源代碼所示(看第一個(gè)int參數(shù)即可),LOCK_IF_MP:會(huì)根據(jù)當(dāng)前處理器的類型來(lái)決定是否為cmpxchg指令添加lock前綴。如果程序是在多處理器上運(yùn)行,就為cmpxchg指令加上lock前綴(lock cmpxchg)。反之,如果程序是在單處理器上運(yùn)行,就省略lock前綴(單處理器自身會(huì)維護(hù)單處理器內(nèi)的順序一致性,不需要lock前綴提供的內(nèi)存屏障效果)。
2.2.對(duì)象頭
HotSpot虛擬機(jī)中,對(duì)象在內(nèi)存中存儲(chǔ)的布局可以分為三塊區(qū)域:對(duì)象頭(Header)、實(shí)例數(shù)據(jù)(Instance Data)和對(duì)齊填充(Padding)。 本文只講對(duì)象頭。
HotSpot虛擬機(jī)的對(duì)象頭(Object Header)包括兩部分信息:
第一部分"Mark Word":用于存儲(chǔ)對(duì)象自身的運(yùn)行時(shí)數(shù)據(jù), 如哈希碼(HashCode)、GC分代年齡、鎖狀態(tài)標(biāo)志、線程持有的鎖、偏向線程ID、偏向時(shí)間戳等等.