天天看點

深入了解java虛拟機學習筆記(5)——垃圾收集算法垃圾收集算法一、分代收集理論二、标記-清除算法三、标記-複制算法四、标記-整理算法

垃圾收集算法

垃圾收集算法可劃分為“引用計數式垃圾收集”和“追蹤式垃圾收集”兩大類,這兩類也被稱為“直接垃圾收集”和“間接垃圾收集”。以下全為“追蹤式垃圾收集”。

目錄

  • 垃圾收集算法
  • 一、分代收集理論
  • 二、标記-清除算法
  • 三、标記-複制算法
  • 四、标記-整理算法

一、分代收集理論

  • 弱分代假說:絕大多數對象都是朝生夕滅的。
  • 強分代假說:熬過越多次垃圾收集過程的對象就越難以消亡。
  • 跨代引用假說:跨代引用相對于同代引用來說占極少數。

前兩個假說奠定了常用垃圾收集器的設計原則:收集器應該将Java堆劃分出不同的區域,然後将回收對象依據其年齡(年齡即熬過垃圾收集過程的次數)配置設定到不同的區域之中存儲。

為什麼要引入第三條經驗法則:如果要進行一次隻局限于新生代區域内的收集,但新生代中你的對象是完全有可能被老年代所引用的,為了找出存活的對象,就需要額外周遊整個老年代中的所有對象,這會給記憶體回收帶來很大的性能負擔。

部分收集(Partial GC):指目标不是完整收集整個Java堆的垃圾收集。

  • 新生代收集(Minor GC/Young GC):指目标隻是新生代的收集。
  • 老年代收集(Major GC/Old GC):指目标隻是老年代的垃圾收集。
  • 混合收集(Mixed GC):指目标是收集整個新生代以及部分老年代的垃圾收集。

整堆收集(Full GC):收集整個Java堆和方法區的垃圾收集。

二、标記-清除算法

标記-清除(Mark-Sweep)算法分為“标記”和“清除”兩個階段:首先标記出所有存活的對象,統一回收所有未被标記的對象。

缺點:

  • 執行效率不穩定
  • 記憶體空間的碎片化問題
深入了解java虛拟機學習筆記(5)——垃圾收集算法垃圾收集算法一、分代收集理論二、标記-清除算法三、标記-複制算法四、标記-整理算法

如圖,深色為可回收部分,當回收後,深色部分變為未使用狀态;回收後未使用區塊有很多不連續的,即産生了大量的不連續的記憶體碎片,以後如果程式需要配置設定較大對象時無法找到足夠的連續記憶體,就要提前觸發垃圾收集動作。

三、标記-複制算法

标記-複制(Mark-Copy)算法将可用記憶體按容量劃分為大小相等的兩塊,每次隻是用其中一塊。當這一塊的記憶體用完了,就将還存活的對象複制到另外一塊上面,然後再把已使用過的記憶體空間一次清理掉。

優點:

  • 配置設定記憶體時不需要考慮空間碎片的複雜情況,隻需要按順序配置設定即可

缺點:

  • 如果大多數對象都是存活的,會産生大量記憶體間複制的開銷
  • 該複制短發将記憶體縮小為原來的一半,空間浪費過大
深入了解java虛拟機學習筆記(5)——垃圾收集算法垃圾收集算法一、分代收集理論二、标記-清除算法三、标記-複制算法四、标記-整理算法

四、标記-整理算法

标記-整理(Mark-Compact)算法,先對對象進行标記,然後所有存活的對象都向記憶體空間一端移動,然後直接清理掉邊界以外的記憶體。

優點:

  • 記憶體配置設定時較為簡單,由于記憶體配置設定和通路相比垃圾收集的頻率要高得多,是以不移動對象總吞吐量會高一些。

缺點:

  • 記憶體回收更為複雜
  • 移動存活對象停頓時間會更長(這個停頓是全程暫停使用者應用程式)
    深入了解java虛拟機學習筆記(5)——垃圾收集算法垃圾收集算法一、分代收集理論二、标記-清除算法三、标記-複制算法四、标記-整理算法