GC簡介
1 GC機制
1.1 對象
從計算機的角度,裝有數據的內存空間
1.2 作用
將內存垃圾的釋放自動化
1.3 本質
將已經引用不到的對象視為死亡,將死亡的對象找出來並且作為垃圾進行回收
2 GC算法
2.1 跟蹤回收
2.1.1 原理
從根開始掃描判斷對象的生死
2.1.2 標記清除
(1)過程
- 第一次掃描:以變量或運行棧作為根,從根開始將可能被引用的對象進行標記,將沒被標記的對象進行垃圾回收
- 第二次掃描:將全部對象進行掃描,對沒有被標記的對象進行垃圾回收,掃描的同時還需要將存活的對象的標記去除
(2)缺點
- 處理時間與對象數量相關,在大量對象且極少存活的情況下,效率不明顯
- 由復制收集解決這一問題
2.1.3 復制收集
(1)過程
- 掃描一遍:將根對象復制到新開辟的內存空間,再用復制的對象所能引用的對象進行遞歸復制
- 清除舊空間
(2)優缺點
- 掃描一遍就相當於標記清除的標記階段,清除階段開銷極小
- cache局部性,復制收集按照引用將關聯的對象復制到新空間,在內存空間里距離較近,效率會提高
- 在存活對象大比列存在的情況下,復制對象的開銷會加大
2.2 引用計數
2.2.1 原理
當對象引用發生變化時,利用引用計數更新對象的狀態,判斷對象的生死
2.2.2 引用計數
(1)過程
在對象內部保持一個對該對象的引用計數,當引用發生增減時進行更新
(2)優缺點
- 能夠做到立即釋放垃圾,中斷時間短
- 無法釋放循環引用的對象
- 在並行環境下,需要對計數操作進行加鎖互斥,開銷較大
2.3 跟蹤回收和引用計數的結合
2.3.1 分代回收
(1)原理
大部分對象在短時間里會成為垃圾,而經過一定時間仍然存活下來的往往擁有較長的壽命,所以增加新生的對象的掃描,減少老生對象的掃描
(2)過程
- GC小回收:利用復制收集,將新空間標記為老生代或利用標記清除方式將存活對象標記為老生代,清除死亡對象
- GC大回收(偶爾進行):以全部區域為對象進行GC操作
(3)記錄集
- 在對象引用發生改變時,如果老生代對象引用到了新生代對象,則將引用記錄加入到記錄集
- 需要時刻保持更新,新生代被老生代引用的瞬間就必須更新
(4)寫屏障
需要將添加到記錄集的操作嵌入到對象修改的地方,對所有涉及修改對象的地方進行保護
(5)優缺點
- 減少了需要掃描的對象,縮短GC時間
- 算法受到程序行為,分代數量,大回收的觸發條件的影響
2.3.2 增量回收
(1)原理
- 將GC操作分為多個階段進行
- 與分代回收相似,需要增加寫屏障,防止存活的對象被清除,而該清除的對象沒被清除
(2)優缺點
中斷時間取決於對象的數量,在犧牲總GC時間的情況下,縮短中斷時間
2.3.3 並行回收
(1)原理
- 程序運行和GC同時進行
- 需要寫屏障對狀態進行實時更新
(2)特點
- 在GC的某個階段還是需要暫停程序的運行,無法完全與程序並行
- 未來趨勢
2.4 GC大一統理論
所有的GC算法都是跟蹤回收和引用計數的結合,兩者相互獨立,對其中一方進行改善的技術之中必然存在對另一方的改善技術,而其結果只是兩種的結合
3 思維導圖