1. 程式人生 > >Java基礎篇(JVM)——總領

Java基礎篇(JVM)——總領

符號 x86 工具 ots 一次 xxx 比較 垃圾 int

這篇文章由幾個問題組成,目的是想厘清JVM的一些基本概念,同時最後引出JVM知識體系的幾大塊,以後的文章就圍繞這幾大塊展開。

1. 什麽是JVM?它有什麽作用?

JVM是Java虛擬機的簡寫,Java是先編譯後解釋型的語言,其最初設計的目的是“一次編寫,到處運行”,也就是要實現平臺的無關性,這個特性正是通過使用JVM實現的。

編譯器首先將Java程序編譯成字節碼.class文件,再由JVM加載,解釋成機器指令給不同的系統(從這個意義上說,Java屬於解釋型語言,因為它並非是直接將代碼編譯成機器可以理解的二進制文件)。不同系統的JVM是不一樣的,但是都能處理.class文件,所以不同運行平臺都能處理程序員編寫的同一份Java代碼。而對於其它傳統編程語言來說(如C/C++),由於它和底層密切相關,其基礎類型的字節長度是不一樣的,導致平臺兼容性就差了很多。

2. JVM的特性有哪些?

(1)基於棧的虛擬機:不同於Intel x86和ARM等比較流行的計算機處理器都是基於寄存器[1](register)架構,JVM是基於棧執行的。(通過.class文件反編譯(javap -verbose xxx.class)後的字節碼文件可以看到,JVM是通過棧將指令逐條壓入的)

(2)符號引用:處基本類型以外的所有Java類型都是通過符號引用取得關聯的,而非顯式的基於內存地址的引用。(類加載機制過程是加載-連接-初始化-使用-卸載,其中,連接分成三步:準備、驗證、解析,解析階段的目的就是將符號引用轉變成直接引用)

(3)垃圾回收機制:類的實例由用戶顯式創建,通過垃圾回收機制進行銷毀。

(4)基本類型長度與平臺無關。

(5)網絡字節序:Java .class文件的二進制表示使用的是基於網絡的字節序,即大端(big endian)字節序,保證了各個平臺之間的統一性。

(大端字節序:即低位地址存儲數據的高位值;小端字節序則相反。

網絡字節序是大端字節序,也就是說在網絡傳輸過程中,首先接收到的是數字的高位值。

Intel x86使用小端字節序,RISC[2]系列平臺使用了大端字節序)

3. 有哪些類型的JVM?

最主流的是HotSpot VM,是Sun JDK和open JDK共同使用的VM,由於09年Oracle收購了BEA和Sun,在JDK 1.8之後的HotSpot VM是原來的HotSpot VM和JRockit VM的合並版。

HotSpot VM的優點是可以動態編譯[3],大大提升了程序執行的性能。

其它的還有:IBM的J9 VM、Zing VM等。

另外,Android平臺上的Dalvik,雖然名義上不叫JVM,但它可以將Java代碼轉化成Dalvik可以使用的代碼,其功能基本和JVM相同,也可以歸作JVM。(為此,Oracle還告了Google)

4. 字節碼是什麽?

字節碼是程序代碼到機器碼之間的中間代碼。JVM並非一次性將所有字節碼讀入內存,而是在使用時加載(類加載機制);同時也並非將所有的字節碼都預先解釋成機器碼,而是通過JIT技術,僅解釋部分熱點代碼以提高性能。

可以用JDK自帶的反編譯命令javap -verbose查看字節碼,這時可以看到JVM基於棧的設計,對每個指令都是入棧出棧來執行,另外,還可以看到JVM是符號引用,而非指向直接內存地址的引用;也可以用16進制工具winHex查看字節碼,這時會看到魔數、版本號、常量池(個數、類型等)等信息。

5. JDK、JRE和JVM的關系是什麽?

JDK包含了JRE,還包含開發工具(編譯工具javac、反編譯工具javap、打包工具jar等);

JRE是Java程序運行環境,包含了JVM,還包含其它的程序運行需要的系統API,如rt.jar等。

JVM是運行Java程序的核心,用來處理字節碼、管理內存等。

6. JVM知識體系分哪幾部分?

在我這裏,將JVM知識體系分成五個部分:

(1)類的加載機制;

(2)JVM內存模型和內存結構;

(3)GC策略/算法;

(4)GC分析、JVM調優;

(5)虛擬機性能監控與故障處理。

先總述一下這幾大塊的關系:

對於已有的Java程序代碼,首先將其編譯成字節碼,然後需要加載進內存中,這時要用到類的加載機制(包括類如何加載,什麽時候加載,什麽時候使用與卸載等);加載進內存中需要分配內存空間,所以要了解JVM的內存模型和內存結構;JVM會針對程序進行GC,所以要了解什麽時候GC、如何GC等;接下來還會涉及到JVM調優,調優主要針對的是GC,所以調優之前首先要分析GC的運行情況;最後了解HotSpot虛擬機相關的知識以及虛擬機性能監控和故障處理的知識。

以後JVM的文章大致就圍繞這幾塊展開。

註:

[1] 寄存器:是CPU中的部件,讀寫速度非常快,可用來進行算術和邏輯運算、存儲地址(尋址)等

[2] RISC:即精簡指令集的簡寫。RISC是CPU的一種設計模式,它對指令數目和尋址方式做了精簡,且所有指令的格式一致,指令周期相同,使得硬件只用執行簡單的那部分指令,其它復雜指令則通過簡單指令復合而成。它的實現更容易,並行程度更好,編譯效率更高。

[3] 動態編譯:也可以叫做JIT。Java是先將程序代碼編譯成字節碼,再由虛擬機解釋給不同的機器來執行。使用HotSpot VM,虛擬機可以讀入字節碼之後,不將所有的字節碼都逐條解釋成機器碼存起來,因為這樣效率太低,而是將經常重復執行的“熱點”代碼先解釋成機器碼,並進行優化。這樣可以提高性能。

Java基礎篇(JVM)——總領