VM 對(duì)象頭MarkWord布局
// 32 bits:
// --------
// hash:25 ------------>| age:4 biased_lock:1 lock:2 (normal object)
// JavaThread*:23 epoch:2 age:4 biased_lock:1 lock:2 (biased object)
//
// 64 bits:
// --------
// unused:25 hash:31 -->| unused_gap:1 age:4 biased_lock:1 lock:2 (normal object)
// JavaThread*:54 epoch:2 unused_gap:1 age:4 biased_lock:1 lock:2 (biased object)</pre>
無論是32位VM 還是64位VM绿淋,排列順序都是由高到低。以64VM為例扬绪,即未用到的 25bit驰凛,是在最高位仰泻,而偏向鎖和鎖標(biāo)記為在最低位,占用最低字節(jié)的最低3位。
biased_lock 為偏向鎖標(biāo)記位涨薪,為1代表已開啟偏向鎖窘疮,為0則代表不支持袋哼。
影響
開啟偏向鎖模式時(shí),一個(gè)對(duì)象若計(jì)算過hashcode闸衫,進(jìn)入同步帶嗎塊時(shí)涛贯,則不會(huì)啟用偏向鎖。直接用輕量級(jí)鎖 or 重量級(jí)鎖蔚出。
看以下代碼:
try {
TimeUnit.SECONDS.sleep(5);//延遲5s弟翘,是因?yàn)閂M剛啟動(dòng)時(shí),未開啟偏向鎖骄酗,該值默認(rèn)為4s
} catch (Exception e) {
?
}
Object o = new Object();
System.out.println(ClassLayout.parseInstance(o).toPrintable());
int has = o.hashCode();
System.out.println(ClassLayout.parseInstance(o).toPrintable());</pre>
//輸出結(jié)果
java.lang.Object object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 05 00 00 00 (00000101 00000000 00000000 00000000) (5)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
12 4 (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
java.lang.Object object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 01 e5 00 33 (00000001 11100101 00000000 00110011) (855696641)
4 4 (object header) 7b 00 00 00 (01111011 00000000 00000000 00000000) (123)
8 4 (object header) e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
12 4 (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total</pre>
分析:
先看新建Object 的內(nèi)部布局稀余,其標(biāo)記字最低位為101(10進(jìn)制的5),偏向鎖是成功開啟了的趋翻。
再看計(jì)算完hashcode后對(duì)象的內(nèi)存布局睛琳,其標(biāo)記字最低位為001,此時(shí)卻把偏向鎖關(guān)了踏烙。為什么新建的對(duì)象在計(jì)算hashcode 值之后就不支持偏向了呢师骗?這要從偏向鎖原理去解釋,64位VM markWord 的hash是采用了 31位讨惩,而偏向鎖在進(jìn)入偏向模式時(shí)辟癌,需要在markword中存儲(chǔ) 線程id 的信息,而這兩個(gè)信息用的都是markword 中高56位信息存儲(chǔ)的荐捻,所以會(huì)出現(xiàn)沖突黍少,而偏向時(shí),又沒有額外的空間去存儲(chǔ)對(duì)象的hash 信息靴患,所以一個(gè)對(duì)象在計(jì)算完hash 后仍侥,偏向鎖模式就關(guān)閉了,進(jìn)入同步代碼塊時(shí)鸳君,只能用輕量級(jí)鎖或重量級(jí)鎖农渊。