JVM深入了解
- 一、Java源碼到執行過程
- 二、JVM記憶體結構
- 三、垃圾回收機制
-
-
-
-
- 标記-清除算法
- 複制算法
- 标記-整理算法
- 分代收集算法
-
-
-
一、Java源碼到執行過程
編譯-加載-解釋-執行。
編譯:将源碼檔案編譯成JVM可以解釋的class檔案,編譯過程會對源碼程式做文法分析,語義分析,注解處理等,最後生成位元組碼檔案。即.java檔案編譯成.class檔案。
加載: 包括裝載-連接配接-初始化
.class檔案是通過類的加載器裝載到jvm中的。
java預設有三種類加載器:AppClassLoader,ExtClassLoader,BootstrapClassLoader。

這裡涉及雙親委派模型,當一個類加載器收到類加載請求的時候,它首先不會自己去加載這個類的資訊,而是把該請求轉發給父類加載器,依次向上。所有的類加載請求都會被傳遞到父類加載器中,隻有當父類加載器中無法加載到所需的類,子類加載器才會自己嘗試去加載該類。如果目前類加載器和所有父類加載器都無法加載該類時,抛出ClassNotFindException異常。
二、JVM記憶體結構
1.堆:存放對象執行個體,幾乎所有的對象執行個體都在這裡配置設定記憶體。
2.虛拟機棧:虛拟機棧描述的是Java方法執行的記憶體結構:每個方法被執行的時候都會同時建立一個棧幀用于存儲局部變量表,操作棧,動态連結,方法出口等資訊。
3.本地方法棧:本地方法棧則是為虛拟機使用到的native方法服務。
4.方法區:存儲已被虛拟機加載的類中繼資料資訊。
5.程式計數器:目前線程所執行的位元組碼的行号訓示器。
三、垃圾回收機制
Java程式在JVM運作中會建立很多對象,JVM可以幫我們自動回收不需要的對象。
在判斷哪些對象的時候,有兩種方法:引用計數法,可達性分析法。
回收對象的的算法:
标記-清除算法
最基礎的收集算法,算法分為标記和清除兩個階段,首先标記所有需要回收的對象,在标記完成後統一回收掉所有被标記的對象。
它的主要缺點有兩個:一個是效率問題,标記和清除過程的效率都不高;另一個是空間問題,标記清除後會産生大量不連續的記憶體碎片,空間碎片太多可能會導緻,當程式在以後的運作過程中需要配置設定較大對象時無法找到足夠的連續記憶體而不得不提前觸發另一次垃圾收集動作。
複制算法
為了解決效率問題,一種稱為複制的收集算法出現了,它将可用記憶體按容量劃分為大小相等的兩塊,每次隻使用其中的一塊。當這一塊的記憶體用完了,就将還存活着的對象複制到另外一塊上面,然後再把已使用過的記憶體空間一次清理掉。
标記-整理算法
根據老年代的特點,有人提出了另外一種“标記-整理”算法,标記過程仍然與标記-清除算法一樣,但後續不是直接對可回收對象進行清理,而是讓所有存活的對象都向一端移動,然後直接清理掉端邊界以外的記憶體。
分代收集算法
目前商業虛拟機的垃圾收集都采用分代收集算法,根據對象的存活周期的不同,将記憶體劃分為幾塊。一般把Java堆分為新生代和老年代,這樣可以根據各個年代的特點采用最适當的收集算法。在新生代中,每次垃圾收集是都發現有大批對象死去,隻有少量存活,那就是選用複制算法,隻需要付出少量存活對象的複制成本記憶可以完成收集。而老年代中因為對象存活率高、沒有額外空間對它進行配置設定擔保,就必須使用“标記-清理”或“标記-整理”算法來進行回收。