垃圾回收首先要厘清jvm記憶體中什麼是垃圾什麼不是垃圾。jvm在識别垃圾時并不是使用通常認為的引用計數法,因為引用計數法無法解決兩個對象之間的循環引用問題。為了解決循環引用問題,使用的是根節點周遊法,可以用圖論中的不可達子圖來了解。當從根節點出發進行周遊時,不可達的對象即認為是垃圾,是要進行回收的。
垃圾回收的方法通常有四類。
一、标記-清除法
這種方法分為兩個階段,首先标記jvm中的垃圾記憶體,然後對被标記為垃圾的記憶體對象進行統一回收。缺點是效率不高,容易産生大量的記憶體碎片,當需要較大的連續空間時無法申請到足夠的記憶體。
二、标記-整理法
這種方法也分為兩個階段,首先也是标記垃圾對象,然後将記憶體中的存活對象向前移動覆寫掉被标記為垃圾的對象。這樣每次整理後記憶體中前面都是存活對象,後面都是連續的可用記憶體空間。
三、複制法
把記憶體分為兩塊,使用時隻适用其中的一塊,當這塊記憶體不夠使用時,進行垃圾回收。回收時将現在使用的記憶體中的存活對象複制到另一塊沒有使用的記憶體上,完成後再把已使用的記憶體空間一次清理掉。缺點是記憶體使用效率低,當對象存活率較好時執行較多的複制操作,導緻效率下降。是以現行的商用jvm中都不是按照1:1來配置設定記憶體的。
四、分代回收法
根據對象存活周期不同,将記憶體劃分為幾塊,一般把java對分為新生代和老生代。新生代中有大量的對象死去,是以采用複制法進行垃圾回收。老生代中對象存活率較好,沒有額外的空間對它們進行配置設定擔保,就必須采用标記-清除法或标記-整理法。