Java Object header對(duì)象頭分析

使用JOL研究Java對(duì)象的布局以及對(duì)象頭信息:

-- 對(duì)象里面的屬性是逐個(gè)添加

public class A {

????private String name ;

????private int age;

????private boolean flag;

????private List<String> list;

}



public class JOLExample3 {

????public static void main(String[] args) {

????????A a = new A();

????????out.println(VM.current().details());

????????out.println(ClassLayout.parseInstance(a).toPrintable());

????}

}



運(yùn)行結(jié)果:

-- 對(duì)象A沒(méi)有屬性

sync.demo.A object internals:

OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE

??????0?????4????????(object header)???????????????????????????01 00 00 00 (00000001 00000000 00000000 00000000) (1)

??????4?????4????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)

??????8?????4????????(object header)???????????????????????????18 0a 1f 18 (00011000 00001010 00011111 00011000) (404687384)

?????12?????4????????(loss due to the next object alignment)

Instance size: 16 bytes

Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

-- 對(duì)象A有一個(gè)String類(lèi)型的name屬性

sync.demo.A object internals:

OFFSET??SIZE???????????????TYPE DESCRIPTION???????????????????????????????VALUE

??????0?????4????????????????????(object header)???????????????????????????01 00 00 00 (00000001 00000000 00000000 00000000) (1)

??????4?????4????????????????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)

??????8?????4????????????????????(object header)???????????????????????????18 0a c7 17 (00011000 00001010 11000111 00010111) (398920216)

?????12?????4???java.lang.String A.name????????????????????????????????????null

Instance size: 16 bytes

Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

-- 對(duì)象A有一個(gè)String類(lèi)型的name屬性富弦,和一個(gè)int類(lèi)型的age屬性

sync.demo.A object internals:

OFFSET??SIZE???????????????TYPE DESCRIPTION???????????????????????????????VALUE

??????0?????4????????????????????(object header)???????????????????????????01 00 00 00 (00000001 00000000 00000000 00000000) (1)

??????4?????4????????????????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)

??????8?????4????????????????????(object header)???????????????????????????18 0a d7 17 (00011000 00001010 11010111 00010111) (399968792)

?????12?????4????????????????int A.age?????????????????????????????????????0

?????16?????4???java.lang.String A.name????????????????????????????????????null

?????20?????4????????????????????(loss due to the next object alignment)

Instance size: 24 bytes

Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

-- 對(duì)象A有一個(gè)String類(lèi)型的name屬性母蛛,和一個(gè)int類(lèi)型的age屬性,一個(gè)boolean類(lèi)型的flag屬性

sync.demo.A object internals:

OFFSET??SIZE???????????????TYPE DESCRIPTION???????????????????????????????VALUE

??????0?????4????????????????????(object header)???????????????????????????01 00 00 00 (00000001 00000000 00000000 00000000) (1)

??????4?????4????????????????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)

??????8?????4????????????????????(object header)???????????????????????????18 0a d6 17 (00011000 00001010 11010110 00010111) (399903256)

?????12?????4????????????????int A.age?????????????????????????????????????0

?????16?????1????????????boolean A.flag????????????????????????????????????false

?????17?????3????????????????????(alignment/padding gap)??????????????????

?????20?????4???java.lang.String A.name????????????????????????????????????null

Instance size: 24 bytes

Space losses: 3 bytes internal + 0 bytes external = 3 bytes total

-- 對(duì)象A有一個(gè)String類(lèi)型的name屬性刹淌,和一個(gè)int類(lèi)型的age屬性饶氏,一個(gè)boolean類(lèi)型的flag屬性,一個(gè)List<String>屬性

sync.demo.A object internals:

OFFSET??SIZE???????????????TYPE DESCRIPTION???????????????????????????????VALUE

??????0?????4????????????????????(object header)???????????????????????????01 00 00 00 (00000001 00000000 00000000 00000000) (1)

??????4?????4????????????????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)

??????8?????4????????????????????(object header)???????????????????????????18 0a bf 17 (00011000 00001010 10111111 00010111) (398395928)

?????12?????4????????????????int A.age?????????????????????????????????????0

?????16?????1????????????boolean A.flag????????????????????????????????????false

?????17?????3????????????????????(alignment/padding gap)??????????????????

?????20?????4???java.lang.String A.name????????????????????????????????????null

?????24?????4?????java.util.List A.list????????????????????????????????????null

?????28?????4????????????????????(loss due to the next object alignment)

Instance size: 32 bytes

Space losses: 3 bytes internal + 4 bytes external = 7 bytes total

總結(jié):

從上面的對(duì)象布局中有勾,隨著對(duì)象中的屬性越來(lái)越多疹启,占用的字節(jié)就越來(lái)越大,但是始終是8的倍數(shù)蔼卡,不夠就進(jìn)行填充喊崖;

但是objectheader 始終占用12byte;

總結(jié):

Instance size: 56 bytes 對(duì)象的大泄统选荤懂;都是8的倍數(shù),64位虛擬機(jī)對(duì)象的大小必須是8的倍數(shù)塘砸;

object header:

從上面的結(jié)果可以分析出每個(gè)對(duì)象頭的大小占12byte节仿;這12byte分別包含兩個(gè)word,mark_word 和 klass_word掉蔬;

mark_word:占8byte廊宪,mark_word是我們重點(diǎn)研究的;下面詳細(xì)說(shuō)明眉踱;

klass_word:剩下的4byte是 klass_word挤忙,用于只想對(duì)象的元數(shù)據(jù);比如class模板谈喳;

(loss due to the next object alignment):用于對(duì)其填充册烈,當(dāng)對(duì)象大小不是8的倍數(shù)的時(shí)候,就使用對(duì)象填充使其對(duì)齊婿禽;

官方文檔:

Every object (except array) in memory has 2 machine word header.?The first one is called mark word and the second one is klass word. Btw arrays have extra 32 bit word filled with array’s length.

Mark word?stores identity hashcode, bits used for garbage collection, bits used for locking. To find out more check out the source from OpenJDK.

Klass word?stores ordinary object pointer (oop) to class metadata, which describes the object’s layout, methods, and other type information. To find out more check out the metadata source from OpenJDK.

下面來(lái)看下mark_word中詳細(xì)描述了什么:


// 64 bits:

// --------

// unused:25 hash:31 -->| unused:1 age:4 biased_lock:1 lock:2 (normal object)

// JavaThread*:54 epoch:2 unused:1 age:4 biased_lock:1 lock:2 (biased object)

// PromotedObject*:61 --------------------->| promo_bits:3 ----->| (CMS promoted object)

// size:64 ----------------------------------------------------->| (CMS free block)

以上是JVM源碼注釋

解釋一下其中的名詞:

unused:沒(méi)有被使用

identity_hashcode:用于存儲(chǔ)對(duì)象的hashCode:

identity_hashcode?-identity hashcode of the object which is assigned lazily. If System.identityHashCode(obj) is called, it is calculated and written into the object header. When object is locked the identity hashcode value is moved into the monitor object

age:GC分代年齡赏僧;

age?-?number of garbage collections the object has survived. It is incremented every time an object is copied within the young generation. When the age field reaches the value of max-tenuring-threshold, the object is promoted to the old generation

biased_lock:偏向鎖狀態(tài);

biased_lock?-?contains 1 if the biased locking is enabled for the class. 0 if the biased locking is disabled for the class. To find out more on biased locking check out my previous

lock:對(duì)象狀態(tài)扭倾;分為無(wú)鎖淀零,輕量級(jí)鎖,重量級(jí)鎖膛壹,GC標(biāo)記驾中;

lock?-the lock state of the object. 00 - Lightweight Locked, 01 - Unlocked or Biased, 10 - Heavyweight Locked, 11 - Marked for Garbage Collection. To find out more on locking/synchronization check out synchronization post

無(wú)鎖狀態(tài)的mark_word:

unused:25:無(wú)鎖狀態(tài)下mark wod中前25位沒(méi)有被使用;

identity_hashcode:31:用于存儲(chǔ)對(duì)象hashCode模聋,包括前面的25個(gè)都是用來(lái)存儲(chǔ)對(duì)象的hashCode肩民,所以mark word前56為是用于存儲(chǔ)無(wú)鎖對(duì)象的hashCode;下面會(huì)驗(yàn)證一下java對(duì)象的hashCode是不是存儲(chǔ)在這里面链方;

unused:1:無(wú)鎖狀態(tài)下沒(méi)有使用持痰;

age:4:GC分代年齡;對(duì)象幸存的垃圾收集數(shù)量祟蚀。 每次在年輕一代中復(fù)制對(duì)象時(shí)工窍,它都會(huì)遞增割卖。 當(dāng)年齡字段達(dá)到max-tenuring-threshold的值時(shí),該對(duì)象將被提升為舊一代患雏;

biased_lock:1:偏向鎖標(biāo)識(shí)鹏溯;

lock:2:對(duì)象狀態(tài);

來(lái)看看無(wú)鎖狀態(tài)下的mark_word:

先驗(yàn)證一下前56為是不是用于存儲(chǔ)對(duì)象的hashCode:

public class JOLExample {

????public static void main(String[] args) {

????????A a = new A();

????????out.println("計(jì)算hashcode之前纵苛。剿涮。。");

????????out.println(ClassLayout.parseInstance(a).toPrintable());

????????out.println("計(jì)算對(duì)象a的hashcode攻人,10進(jìn)制:"+a.hashCode());

????????out.println("計(jì)算hashcode之后取试。。怀吻。");

????????out.println(ClassLayout.parseInstance(a).toPrintable());

????}

}

打印如下:

計(jì)算hashcode之前瞬浓。。蓬坡。

sync.demo.A object internals:

OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE

0?????4????????(object header)???????????????????????????01 00 00 00 (00000001?00000000 00000000 00000000) (1)

??????4?????4????????(object header)???????????????????????????00 00 00 00 (00000000?00000000 00000000 00000000) (0)

??????8?????4????????(object header)???????????????????????????18 0a cd 17 (00011000 00001010 11001101 00010111) (399313432)

?????12?????4????????(loss due to the next object alignment)

Instance size: 16 bytes

Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

計(jì)算對(duì)象a的hashcode猿棉,10進(jìn)制:1213415012

計(jì)算hashcode之后。屑咳。萨赁。

sync.demo.A object internals:

OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE

0?????4????????(object header)???????????????????????????01 64 3e 53 (00000001?01100100 00111110 01010011) (1396597761)

??????4?????4????????(object header)???????????????????????????48 00 00 00 (01001000?00000000 00000000 00000000) (72)

??????8?????4????????(object header)???????????????????????????18 0a cd 17 (00011000 00001010 11001101 00010111) (399313432)

?????12?????4????????(loss due to the next object alignment)

Instance size: 16 bytes

Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

通過(guò)進(jìn)制轉(zhuǎn)換工具將對(duì)象的10進(jìn)制hashcode轉(zhuǎn)換成二進(jìn)制:

? ?十六進(jìn)制?? ??? ??? ???? ??? ??? ??? ??? ??? ?二進(jìn)制

1213415012:?? ??? ?01001000 01010011 00111110 01100100

對(duì)象頭中標(biāo)紅的hashcode:

01100100 00111110 01010011?01001000

兩個(gè)進(jìn)行對(duì)比一下:

我們打印出來(lái)并進(jìn)行二進(jìn)制轉(zhuǎn)換的hashCode:??01001000 01010011 00111110 01100100

JOL打印出來(lái)的object header中的hashCoxe:? ??01100100 00111110 01010011?01001000

是不是發(fā)現(xiàn)不一樣?那是因?yàn)閣indows操作系統(tǒng)是小端存儲(chǔ)兆龙,是反過(guò)來(lái)的杖爽;我們來(lái)翻轉(zhuǎn)一下:

我們打印出來(lái)并進(jìn)行二進(jìn)制轉(zhuǎn)換的hashCode:??01001000 01010011 00111110 01100100

JOL打印出來(lái)的object header中的hashCoxe:? ??01001000?01010011?00111110?01100100

一樣的吧,說(shuō)明官方文檔中說(shuō)是對(duì)的紫皇;

最后來(lái)研究一下mark word中最后8bit慰安,也是最終的8bit;

unused:1 age:4 biased_lock:1 lock:2

分別存儲(chǔ)GC分代年齡聪铺,偏向鎖標(biāo)識(shí)化焕,對(duì)象狀態(tài);見(jiàn)下圖铃剔;

JOL打印中的最后8bit:?00000001

? ? ? ? 0? ? ? ? ? ? ? ? ? ?0000? ? ? ? ? ? ? 0? ? ? ? ? ? ? ?01

沒(méi)有被使用? ? ? GC分代年齡? ? 偏向標(biāo)識(shí)? ? 對(duì)象狀態(tài)

我們著重分析一下最后三位撒桨,其中最后兩位是用于標(biāo)識(shí)對(duì)象狀態(tài),也就是鎖狀態(tài)键兜,Java中的對(duì)象狀態(tài)有:無(wú)鎖凤类,偏向鎖,輕量鎖蝶押,重量鎖踱蠢,GC標(biāo)識(shí)五種狀態(tài)火欧;

那么最后兩位最多組合只能表示4中狀態(tài):00棋电,01茎截,10,11赶盔,JVM怎么表示五種狀態(tài)呢胜臊?

答案就是JVM把偏向鎖和無(wú)鎖表示為同一種狀態(tài)隶校,隨后通過(guò)偏向標(biāo)識(shí),來(lái)區(qū)分偏向鎖和無(wú)鎖,當(dāng)偏向鎖的時(shí)候规伐,偏向標(biāo)識(shí)是1,對(duì)象狀態(tài)是01疚脐,下面會(huì)具體分析溪烤;

因?yàn)樯厦娲a中并沒(méi)有對(duì)對(duì)象A進(jìn)行加鎖操作,所以打印出來(lái)的是無(wú)鎖狀態(tài)闷叉,可以判定擦俐,在無(wú)鎖時(shí)的mark_word中對(duì)象頭的偏向標(biāo)識(shí)是不可偏向0,且對(duì)象狀態(tài)是01握侧,代表無(wú)鎖蚯瞧;


public class JOLExample {

????static A a ;

????public static void main(String[] args) throws InterruptedException {

????????a = new A();

????????out.println("對(duì)象A加鎖之前。品擎。埋合。"); //預(yù)期應(yīng)該是無(wú)鎖

????????out.println(ClassLayout.parseInstance(a).toPrintable());

????????sync();

????????out.println("對(duì)象A加鎖之后。萄传。甚颂。"); //預(yù)期應(yīng)該是偏向鎖

????????out.println(ClassLayout.parseInstance(a).toPrintable());

????}

????public static void sync(){

????????synchronized (a){

????????????out.println("對(duì)象A加鎖中 ing 。盲再。西设。"); //預(yù)期應(yīng)該是無(wú)鎖

????????????out.println(ClassLayout.parseInstance(a).toPrintable());

????????}

????}

}

結(jié)果:

對(duì)象A加鎖之前。答朋。贷揽。

sync.demo.A object internals:

OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE

??????0?????4????????(object header)???????????????????????????01 00 00 00 (00000001?00000000 00000000 00000000) (1)

??????4?????4????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)

??????8?????4????????(object header)???????????????????????????18 0a f0 17 (00011000 00001010 11110000 00010111) (401607192)

?????12?????4????????(loss due to the next object alignment)

Instance size: 16 bytes

Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

對(duì)象A加鎖中 ing 。梦碗。禽绪。

sync.demo.A object internals:

OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE

??????0?????4????????(object header)???????????????????????????30 f1 91 03 (00110000?11110001 10010001 00000011) (59896112)

??????4?????4????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)

??????8?????4????????(object header)???????????????????????????18 0a f0 17 (00011000 00001010 11110000 00010111) (401607192)

?????12?????4????????(loss due to the next object alignment)

Instance size: 16 bytes

Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

對(duì)象A加鎖之后。洪规。印屁。

sync.demo.A object internals:

OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE

??????0?????4????????(object header)???????????????????????????01 00 00 00 (00000001?00000000 00000000 00000000) (1)

??????4?????4????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)

??????8?????4????????(object header)???????????????????????????18 0a f0 17 (00011000 00001010 11110000 00010111) (401607192)

?????12?????4????????(loss due to the next object alignment)

Instance size: 16 bytes

Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

從上面的打印結(jié)果我們可以知道,上面執(zhí)行的代碼斩例,并沒(méi)有資源競(jìng)爭(zhēng)雄人,至始至終都是main線程在執(zhí)行,在Java1.6之前,JVM中synchronized關(guān)鍵字的實(shí)現(xiàn)方式是調(diào)用操作系統(tǒng)底層的pthread_mutex_t? 函數(shù)實(shí)現(xiàn)加鎖础钠,而1.6之后進(jìn)行了優(yōu)化恰力,在沒(méi)有資源競(jìng)爭(zhēng)的情況下,JVM的加鎖應(yīng)該是偏向鎖旗吁,但是從結(jié)果中看踩萎,肯定不是偏向鎖,因?yàn)槠驑?biāo)識(shí)是0很钓,這里的000是一個(gè)輕量鎖香府,因?yàn)闆](méi)有資源競(jìng)爭(zhēng),肯定不是重量級(jí)鎖码倦,那么怎樣才能看到偏向鎖呢企孩?為什么這里默認(rèn)就從無(wú)鎖升級(jí)為輕量鎖了呢?看下一一段代碼

public class JOLExample1 {

????static A a ;

????public static void main(String[] args) throws InterruptedException {

????????//延遲5秒

????????Thread.sleep(5000);

????????a = new A();

????????out.println("對(duì)象A加鎖之前袁稽。柠硕。。");

????????out.println(ClassLayout.parseInstance(a).toPrintable());

????????sync();

????????out.println("對(duì)象A加鎖之后运提。蝗柔。。");

????????out.println(ClassLayout.parseInstance(a).toPrintable());

????}

????public static void sync(){

????????synchronized (a){

????????????out.println("對(duì)象A加鎖中 ing 民泵。癣丧。。");

????????????out.println(ClassLayout.parseInstance(a).toPrintable());

????????}

????}

}

運(yùn)行結(jié)果:

對(duì)象A加鎖之前栈妆。胁编。。

sync.demo.A 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)???????????????????????????18 0a c1 17 (00011000 00001010 11000001 00010111) (398527000)

?????12?????4????????(loss due to the next object alignment)

Instance size: 16 bytes

Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

對(duì)象A加鎖中 ing 鳞尔。嬉橙。。

sync.demo.A object internals:

OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE

??????0?????4????????(object header)???????????????????????????05 f8 c6 02 (00000101?11111000 11000110 00000010) (46594053)

??????4?????4????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)

??????8?????4????????(object header)???????????????????????????18 0a c1 17 (00011000 00001010 11000001 00010111) (398527000)

?????12?????4????????(loss due to the next object alignment)

Instance size: 16 bytes

Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

對(duì)象A加鎖之后寥假。市框。。

sync.demo.A object internals:

OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE

??????0?????4????????(object header)???????????????????????????05 f8 c6 02 (00000101?11111000 11000110 00000010) (46594053)

??????4?????4????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)

??????8?????4????????(object header)???????????????????????????18 0a c1 17 (00011000 00001010 11000001 00010111) (398527000)

?????12?????4????????(loss due to the next object alignment)

Instance size: 16 bytes

Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

打印結(jié)果出來(lái)了糕韧,有沒(méi)有被嚇到枫振,101,偏向鎖萤彩;

兩個(gè)疑問(wèn):

1.為什么延遲5秒粪滤,執(zhí)行同步代碼塊時(shí)是偏向鎖?

2.為什么對(duì)象一開(kāi)始就已經(jīng)是偏向鎖雀扶,不應(yīng)該是無(wú)鎖嗎杖小?

再看一個(gè)運(yùn)行結(jié)果:在JVM執(zhí)行參數(shù)中加入-XX:BiasedLockingStartupDelay=0,一會(huì)在解釋這個(gè)參數(shù)有什么作用

運(yùn)行結(jié)果:

對(duì)象A加鎖之前。予权。县踢。

sync.demo.A 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)???????????????????????????18 0a dd 17 (00011000 00001010 11011101 00010111) (400362008)

?????12?????4????????(loss due to the next object alignment)

Instance size: 16 bytes

Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

對(duì)象A加鎖中 ing 。伟件。。

sync.demo.A object internals:

OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE

??????0?????4????????(object header)???????????????????????????05 f8 c9 02 (00000101?11111000 11001001 00000010) (46790661)

??????4?????4????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)

??????8?????4????????(object header)???????????????????????????18 0a dd 17 (00011000 00001010 11011101 00010111) (400362008)

?????12?????4????????(loss due to the next object alignment)

Instance size: 16 bytes

Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

對(duì)象A加鎖之后议经。斧账。。

sync.demo.A object internals:

OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE

??????0?????4????????(object header)???????????????????????????05 f8 c9 02 (00000101?11111000 11001001 00000010) (46790661)

??????4?????4????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)

??????8?????4????????(object header)???????????????????????????18 0a dd 17 (00011000 00001010 11011101 00010111) (400362008)

?????12?????4????????(loss due to the next object alignment)

Instance size: 16 bytes

Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

上面的代碼關(guān)閉睡眠煞肾,加上了-XX:BiasedLockingStartupDelay=0這個(gè)運(yùn)行參數(shù)咧织,為什么對(duì)象一開(kāi)始就是偏向鎖了呢?前面例子不是在沒(méi)有睡眠之前是無(wú)鎖的呀籍救,為什么現(xiàn)在一上來(lái)就變成偏向鎖习绢?

-XX:BiasedLockingStartupDelay=0 就是這個(gè)參數(shù)的原因,這個(gè)參數(shù)是禁止偏向鎖延遲蝙昙,因?yàn)镴VM默認(rèn)是延遲開(kāi)啟偏向鎖的闪萄,時(shí)間大概是4秒左右,那JVM為什么要延遲開(kāi)啟偏向鎖呢奇颠?那是因?yàn)榘苋ィ贘VM啟動(dòng)的時(shí)候,JVM認(rèn)為在JVM啟動(dòng)的時(shí)候烈拒,JVM的運(yùn)行程序中的同步代碼都是存在資源競(jìng)爭(zhēng)的圆裕,沒(méi)有必要開(kāi)啟偏向鎖的必要,等我JVM啟動(dòng)完了荆几,在開(kāi)啟偏向鎖供用戶使用吓妆。所以就出現(xiàn)了前面的差異;

總結(jié)一下Java Object header:

Java對(duì)象頭一共占12byte吨铸,其中mark word占8byte行拢,klass占4byte;

鎖狀態(tài):

001:無(wú)鎖

101:偏向鎖

000:輕量級(jí)鎖

010:重量級(jí)鎖

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末诞吱,一起剝皮案震驚了整個(gè)濱河市剂陡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌狐胎,老刑警劉巖鸭栖,帶你破解...
    沈念sama閱讀 211,042評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異握巢,居然都是意外死亡晕鹊,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)溅话,“玉大人晓锻,你說(shuō)我怎么就攤上這事》杉福” “怎么了砚哆?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,674評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)屑墨。 經(jīng)常有香客問(wèn)我躁锁,道長(zhǎng),這世上最難降的妖魔是什么卵史? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,340評(píng)論 1 283
  • 正文 為了忘掉前任战转,我火速辦了婚禮,結(jié)果婚禮上以躯,老公的妹妹穿的比我還像新娘槐秧。我一直安慰自己,他們只是感情好忧设,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布刁标。 她就那樣靜靜地躺著,像睡著了一般址晕。 火紅的嫁衣襯著肌膚如雪命雀。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,749評(píng)論 1 289
  • 那天斩箫,我揣著相機(jī)與錄音吏砂,去河邊找鬼。 笑死乘客,一個(gè)胖子當(dāng)著我的面吹牛狐血,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播易核,決...
    沈念sama閱讀 38,902評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼匈织,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了牡直?” 一聲冷哼從身側(cè)響起缀匕,我...
    開(kāi)封第一講書(shū)人閱讀 37,662評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎碰逸,沒(méi)想到半個(gè)月后乡小,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡饵史,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年满钟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了胜榔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,577評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡湃番,死狀恐怖夭织,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情吠撮,我是刑警寧澤尊惰,帶...
    沈念sama閱讀 34,258評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站泥兰,受9級(jí)特大地震影響弄屡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜逾条,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望投剥。 院中可真熱鬧师脂,春花似錦、人聲如沸江锨。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,726評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)啄育。三九已至酌心,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間挑豌,已是汗流浹背安券。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,952評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留氓英,地道東北人侯勉。 一個(gè)月前我還...
    沈念sama閱讀 46,271評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像铝阐,于是被迫代替她去往敵國(guó)和親址貌。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容