垃圾收集算法
垃圾收集算法可劃分為“引用計數式垃圾收集”和“追蹤式垃圾收集”兩大類,這兩類也被稱為“直接垃圾收集”和“間接垃圾收集”。以下全為“追蹤式垃圾收集”。
目錄
- 垃圾收集算法
- 一、分代收集理論
- 二、标記-清除算法
- 三、标記-複制算法
- 四、标記-整理算法
一、分代收集理論
- 弱分代假說:絕大多數對象都是朝生夕滅的。
- 強分代假說:熬過越多次垃圾收集過程的對象就越難以消亡。
- 跨代引用假說:跨代引用相對于同代引用來說占極少數。
前兩個假說奠定了常用垃圾收集器的設計原則:收集器應該将Java堆劃分出不同的區域,然後将回收對象依據其年齡(年齡即熬過垃圾收集過程的次數)配置設定到不同的區域之中存儲。
為什麼要引入第三條經驗法則:如果要進行一次隻局限于新生代區域内的收集,但新生代中你的對象是完全有可能被老年代所引用的,為了找出存活的對象,就需要額外周遊整個老年代中的所有對象,這會給記憶體回收帶來很大的性能負擔。
部分收集(Partial GC):指目标不是完整收集整個Java堆的垃圾收集。
- 新生代收集(Minor GC/Young GC):指目标隻是新生代的收集。
- 老年代收集(Major GC/Old GC):指目标隻是老年代的垃圾收集。
- 混合收集(Mixed GC):指目标是收集整個新生代以及部分老年代的垃圾收集。
整堆收集(Full GC):收集整個Java堆和方法區的垃圾收集。
二、标記-清除算法
标記-清除(Mark-Sweep)算法分為“标記”和“清除”兩個階段:首先标記出所有存活的對象,統一回收所有未被标記的對象。
缺點:
- 執行效率不穩定
- 記憶體空間的碎片化問題
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL9EFRPFTTqJGboJzYxI0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL0YTNzQzMzMjM5ETNwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
如圖,深色為可回收部分,當回收後,深色部分變為未使用狀态;回收後未使用區塊有很多不連續的,即産生了大量的不連續的記憶體碎片,以後如果程式需要配置設定較大對象時無法找到足夠的連續記憶體,就要提前觸發垃圾收集動作。
三、标記-複制算法
标記-複制(Mark-Copy)算法将可用記憶體按容量劃分為大小相等的兩塊,每次隻是用其中一塊。當這一塊的記憶體用完了,就将還存活的對象複制到另外一塊上面,然後再把已使用過的記憶體空間一次清理掉。
優點:
- 配置設定記憶體時不需要考慮空間碎片的複雜情況,隻需要按順序配置設定即可
缺點:
- 如果大多數對象都是存活的,會産生大量記憶體間複制的開銷
- 該複制短發将記憶體縮小為原來的一半,空間浪費過大
四、标記-整理算法
标記-整理(Mark-Compact)算法,先對對象進行标記,然後所有存活的對象都向記憶體空間一端移動,然後直接清理掉邊界以外的記憶體。
優點:
- 記憶體配置設定時較為簡單,由于記憶體配置設定和通路相比垃圾收集的頻率要高得多,是以不移動對象總吞吐量會高一些。
缺點:
- 記憶體回收更為複雜
- 移動存活對象停頓時間會更長(這個停頓是全程暫停使用者應用程式)
深入了解java虛拟機學習筆記(5)——垃圾收集算法垃圾收集算法一、分代收集理論二、标記-清除算法三、标記-複制算法四、标記-整理算法