JVM記憶體回收演算法,jvm記憶體回收
1 標記-清理演算法:最基礎的記憶體回收演算法,正如他的名字一樣,演算法分為標記和清理兩個步驟:首先標記出需要清理的對象,在標記完成後統一回收掉所有標記的對象,此演算法的缺點:一個是效率問題,標記和清除過程的效率都不高,另外一個是空間問題,標記清除後會
產生大量不聯絡的記憶體片段,空間片段太多可能回導致當程式在以後的運行過程中需要分配較大對象時無法找到足夠的連續記憶體而不得不提前觸發另外一次記憶體回收動作.
2 複製演算法,為瞭解決標記清除演算法的效率問題,一種稱為複製(Copying)的演算法出現了,它將可用記憶體按照容量劃分為大小相等的兩塊,每次只使用其中的一塊,當一塊使用完了,就將記憶體活著的對象複製到另外一塊上面,然後把已經使用過的記憶體空間一次清理掉,
這樣使得每次都是對其中的一塊記憶體進行回收操作,記憶體配置的時候也就不需要考慮記憶體片段等相關問題了,只要移動堆頂指標即可,實現簡單,運行高效.這種演算法的代價就是將記憶體縮小為原來的一半,未必代價有點高,複製演算法執行過程如下:
3 標記整理演算法 複製收集演算法在對象存活率較高時就要執行較多的複製操作 ,效率會受到一定影響,更關鍵的是,如果不想浪費掉50%的空間,就需要額外的空間進行分配擔保,以應對被使用的記憶體中所有對象都100%存活的極端情況,所以在老年代一般不能直接選擇這種演算法.
根據老年代的特點有人提出另外一種標記--整理的演算法,標記-整理演算法和"標記-清除"演算法一樣,但是後續步驟不是直接對可回收的對象進行清理,而是讓所有存活的對象都向一端移動,然後直接清理掉端邊界之外的記憶體,"標記-整理演算法"的過程如:
4 分代收集演算法 根據對象的的存活周期的不同將記憶體劃分為幾塊,一般是把Java堆分為新生代和老年代,這樣就可以根據各個年代的特點採用最適當的收集演算法.在新生代中,每次垃圾收集的時候都出現大批量對象死去,只要少量存活,就選用複製演算法,只需要
付出少量存活 對象的複製成本就可以完成收集.而老年代中因為對象存活率比較高,沒有額外的空間對它進行分配擔保,就必須使用"標記-清除"或"標記-整理"演算法來進行回收.
5 垃圾收集器,主要的垃圾收集器有Serial收集器,ParNew收集器,Parallel Scavenge收集器,Serial Old收集器,Parallel Old收集器,CMS收集器,G1收集器
參考資料:深入理解Java虛擬機器