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