垃圾收集算法
標記-清除算法
最基礎的收集算法是”標記-清除”(Mark-Sweep)算法,算法分為“標記”和“清除”兩個階段:首先標記出所有需要回收的對象,在標記完成後統一回收所有被標記的對象。標記-清除算法主要有兩個不足:一個是效率問題,標記和清除兩個過程的效率,另一個是空間問題,標記清除之後會產生大量不連續的內存碎片,空間kongjian碎片太多可能會導致以後在程序運行過程中需要分配較大對象時,無法找到足夠的連續內存而不得不提前觸發另一次垃圾收集動作,標記-清除算法的執行過程如圖:
這裡寫圖片描述
復制算法
復制算法(conying)他將內存按容量劃分為大小相等的兩塊,每次只使用其中一塊,當這一塊的內存用完了,就將還存活著的對象復制到另一塊上面,然後把已經使用過的內存一次性清理掉。這樣使得每次都對整半個內存進行回收,但是這種算法的代價是將內存縮小了一半,代價太高了。
如圖:
標記-整理算法
標記-整理算法(Mark-Compact)的標記過程任然與“標記-清除”算法一樣,但後續步驟不是直接對可回收對象進行清理,而是讓所有存活的對象都像一段移動,然後直接清理掉端邊界以外的內存,“標記-整理”算法示意圖:
分代收集算法
一般是把Java堆分為新生代和老年代,這樣就可以根據各個年代的特點采用最適合的收集算法。在新生代中每次垃圾收集時都發現大批對象死去,只有少量存活,就選用復制算法,只需要付出少量存活對象的復制成本就可以完成收集。而老年代中因為對象存活率高,沒有額外空間對他進行分配擔保,就必須使用“標記-清理”和“標記-整理”算法來進行回收。
PS:文章的來源是看完周志明的深入理解Java虛擬機後做的筆記。
深入理解Java虛擬機:JVM高級特性與最佳實踐 第2版 高清PDF+源碼 http://www.linuxidc.com/Linux/2014-09/106869.htm