在2008年和2009年,Oracle公司分別收購(gòu)了BEA公司和Sun公司,這樣Oracle就同時(shí)擁有了兩款優(yōu)秀的java虛擬機(jī):JRockit VM和HotSpot VM。Oracle公司宣布在不久的將來(lái)(大約應(yīng)在發(fā)布JDK 8的時(shí)候)會(huì)完成這兩款虛擬機(jī)的整合工作,使之優(yōu)勢(shì)互補(bǔ)。整合的方式大致上是在HotSpot的基礎(chǔ)上,移植JRockit的優(yōu)秀特性,譬如使用JRockit的垃圾回收器與MissionControl服務(wù),使用HotSpot的JIT解釋與編譯 混合混合的運(yùn)行時(shí)系統(tǒng)。HotSpot VM的熱點(diǎn)代碼探測(cè)能力可以通過(guò)執(zhí)行計(jì)數(shù)器找出最具有編譯價(jià)值的代碼,然后通知JIT編譯器以方法為單位進(jìn)行編譯。如果一個(gè)方法被頻繁調(diào)用,或方法中有效循環(huán)次數(shù)很多,將會(huì)分別觸發(fā)標(biāo)準(zhǔn)編譯和OSR(棧上替換)編譯動(dòng)作。通過(guò)編譯器與解釋器恰當(dāng)?shù)貐f(xié)同工作,可以在最優(yōu)化的程序響應(yīng)時(shí)間與最佳執(zhí)行性能中取得平衡,而且無(wú)須等待本地代碼輸出才能執(zhí)行程序,即時(shí)編譯的時(shí)間壓力也相對(duì)減小,這樣有助于引入更多的代碼優(yōu)化技術(shù),輸出質(zhì)量更高的本地代碼。編譯器是把源程序的每一條語(yǔ)句都編譯成機(jī)器語(yǔ)言,并保存成二進(jìn)制文件,這樣運(yùn)行時(shí)計(jì)算機(jī)可以直接以機(jī)器語(yǔ)言來(lái)運(yùn)行此程序,速度很快;而解釋器則是只在執(zhí)行程序時(shí),才一條一條的解釋成機(jī)器語(yǔ)言給計(jì)算機(jī)來(lái)執(zhí)行,所以運(yùn)行速度是不如編譯后的程序運(yùn)行的快的.動(dòng)態(tài)編譯(compile during run-time),英文稱Dynamic compilation;Just In Time也是這個(gè)意思。
HotSpot對(duì)bytecode的編譯不是在程序運(yùn)行前編譯的,而是在程序運(yùn)行過(guò)程中編譯的。
java -version
Java HotSpot(TM) Client VM (build 14.3-b01, mixed mode, sharing)
mixed mode 解釋與編譯 混合的執(zhí)行模式 默認(rèn)使用這種模式
java -Xint -version
Java HotSpot(TM) Client VM (build 14.3-b01, interPReted mode, sharing)
interpreted 純解釋模式 禁用JIT編譯
java -Xcomp -version
Java HotSpot(TM) Client VM (build 14.3-b01, compiled mode, sharing)
compiled 純編譯模式(如果方法無(wú)法編譯,則回退到解釋模式執(zhí)行無(wú)法編譯的方法)
http://blog.csdn.net/u010425776/article/details/511908012)對(duì)象的創(chuàng)建過(guò)程
當(dāng)虛擬機(jī)遇到一條含有new的指令時(shí),會(huì)進(jìn)行一系列對(duì)象創(chuàng)建的操作:
檢查常量池中是否有即將要?jiǎng)?chuàng)建的這個(gè)對(duì)象所屬的類的符號(hào)引用;
若常量池中沒(méi)有這個(gè)類的符號(hào)引用,說(shuō)明這個(gè)類還沒(méi)有被定義!拋出ClassNotFoundException;若常量池中有這個(gè)類的符號(hào)引用,則進(jìn)行下一步工作;進(jìn)而檢查這個(gè)符號(hào)引用所代表的類是否已經(jīng)被JVM加載;
若該類還沒(méi)有被加載,就找該類的class文件,并加載進(jìn)方法區(qū);若該類已經(jīng)被JVM加載,則準(zhǔn)備為對(duì)象分配內(nèi)存;根據(jù)方法區(qū)中該類的信息確定該類所需的內(nèi)存大小; 一個(gè)對(duì)象所需的內(nèi)存大小是在這個(gè)對(duì)象所屬類被定義完就能確定的!且一個(gè)類所生產(chǎn)的所有對(duì)象的內(nèi)存大小是一樣的!JVM在一個(gè)類被加載進(jìn)方法區(qū)的時(shí)候就知道該類生產(chǎn)的每一個(gè)對(duì)象所需要的內(nèi)存大小。
從堆中劃分一塊對(duì)應(yīng)大小的內(nèi)存空間給新的對(duì)象; 分配堆中內(nèi)存有兩種方式:
指針碰撞 如果JVM的垃圾收集器采用復(fù)制算法或標(biāo)記-整理算法,那么堆中空閑內(nèi)存是完整的區(qū)域,并且空閑內(nèi)存和已使用內(nèi)存之間由一個(gè)指針標(biāo)記。那么當(dāng)為一個(gè)對(duì)象分配內(nèi)存時(shí),只需移動(dòng)指針即可。因此,這種在完整空閑區(qū)域上通過(guò)移動(dòng)指針來(lái)分配內(nèi)存的方式就叫做“指針碰撞”。空閑列表 如果JVM的垃圾收集器采用標(biāo)記-清除算法,那么堆中空閑區(qū)域和已使用區(qū)域交錯(cuò),因此需要用一張“空閑列表”來(lái)記錄堆中哪些區(qū)域是空閑區(qū)域,從而在創(chuàng)建對(duì)象的時(shí)候根據(jù)這張“空閑列表”找到空閑區(qū)域,并分配內(nèi)存。 綜上所述:JVM究竟采用哪種內(nèi)存分配方法,取決于它使用了何種垃圾收集器。為對(duì)象中的成員變量賦上初始值(默認(rèn)初始化);
設(shè)置對(duì)象頭中的信息;
調(diào)用對(duì)象的構(gòu)造函數(shù)進(jìn)行初始化 此時(shí),整個(gè)對(duì)象的創(chuàng)建過(guò)程就完成了。
對(duì)象的內(nèi)存模型
一個(gè)對(duì)象從邏輯角度看,它由成員變量和成員函數(shù)構(gòu)成,從物理角度來(lái)看,對(duì)象是存儲(chǔ)在堆中的一串二進(jìn)制數(shù),這串二進(jìn)制數(shù)的組織結(jié)構(gòu)如下。
對(duì)象在內(nèi)存中分為三個(gè)部分:
對(duì)象頭實(shí)例數(shù)據(jù)對(duì)齊補(bǔ)充1. 對(duì)象頭
對(duì)象頭中記錄了對(duì)象在運(yùn)行過(guò)程中所需要使用的一些數(shù)據(jù):哈希碼、GC分代年齡、鎖狀態(tài)標(biāo)志、線程持有的鎖、偏向線程ID、偏向時(shí)間戳等。
此外,對(duì)象頭中可能還包含類型指針。通過(guò)該指針能確定這個(gè)對(duì)象所屬哪個(gè)類。
此外,如果對(duì)象是一個(gè)數(shù)組,那么對(duì)象頭中還要包含數(shù)組長(zhǎng)度。
2. 實(shí)例數(shù)據(jù)
實(shí)力數(shù)據(jù)部分就是成員變量的值,其中包含父類的成員變量和本類的成員變量。
3. 對(duì)齊補(bǔ)充
用于確保對(duì)象的總長(zhǎng)度為8字節(jié)的整數(shù)倍。 HotSpot要求對(duì)象的總長(zhǎng)度必須是8字節(jié)的整數(shù)倍。由于對(duì)象頭一定是8字節(jié)的整數(shù)倍,但實(shí)例數(shù)據(jù)部分的長(zhǎng)度是任意的,因此需要對(duì)齊補(bǔ)充字段確保整個(gè)對(duì)象的總長(zhǎng)度為8的整數(shù)倍。
訪問(wèn)對(duì)象的過(guò)程
我們知道,引用類型的變量中存放的是一個(gè)地址,那么根據(jù)地址類型的不同,對(duì)象有不同的訪問(wèn)方式:
句柄訪問(wèn)方式 堆中需要有一塊叫做“句柄池”的內(nèi)存空間,用于存放所有對(duì)象的地址和所有對(duì)象所屬類的類信息。 引用類型的變量存放的是該對(duì)象在句柄池中的地址。訪問(wèn)對(duì)象時(shí),首先需要通過(guò)引用類型的變量找到該對(duì)象的句柄,然后根據(jù)句柄中對(duì)象的地址再訪問(wèn)對(duì)象。
直接指針訪問(wèn)方式 引用類型的變量直接存放對(duì)象的地址,從而不需要句柄池,通過(guò)引用能夠直接訪問(wèn)對(duì)象。 但對(duì)象所在的內(nèi)存空間中需要額外的策略存儲(chǔ)對(duì)象所屬的類信息的地址。
比較
HotSpot采用直接指針?lè)绞皆L問(wèn)對(duì)象,因?yàn)樗恍枰淮螌ぶ凡僮鳎瑥亩阅鼙染浔L問(wèn)方式快一倍。但它需要額外的策略存儲(chǔ)對(duì)象在方法區(qū)中類信息的地址。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注