Java常見的垃圾收集器GC算法整理

一.題記

Java垃圾回收器的概念看完一遍總是不能深入的理解和記憶,本文主要是對讀完《深入理解java虛擬機》一書的整理,以便後續複習之用。

二.概述

1.GC概念

在Java中,當沒有對象引用指向原先分配給某個對象的內存時,該內存便成爲垃圾。JVM的一個系統級線程會自動釋放該內存塊。垃圾收集意味着程序不再需要的對象是"無用信息",這些信息將被丟棄。當一個對象不再被引用的時候,內存回收它佔領的空間,以便空間被後來的新對象使用。事實上,除了釋放沒用的對象,垃圾收集也可以清除內存記錄碎片。由於創建對象和垃圾收集器釋放丟棄對象所佔的內存空間,內存會出現碎片。碎片是分配給對象的內存塊之間的空閒內存洞。碎片整理將所佔用的堆內存移到堆的一端,JVM將整理出的內存分配給新的對象。

2.GC算法

對於垃圾回收可以從基本回收策略、分區對待方式、系統線程進行劃分。

(1).基本回收策略

1).引用計數器(Reference Counting)

說明:引用計數器是垃圾收集器早期的算法,是唯一沒有使用根級的垃圾回收法,通過使用引用計數器來區分存活對象和不再使用的對象,通常堆中的每個對象都會對應一個引用計數器,當每次創建一個對象並指向其引用被賦給一個變量時,該對象的引用計數器被設置爲1。以後每當其引用被賦值給一個不同的變量時,該對象的引用計數就加1,當對象丟棄不在使用既出了作用域,該對象的引用計數器減1。任一對象一旦其引用計數器爲0,對象就滿足了垃圾回收條件。

優點:引用計數收集器算法簡單,適於做增量收集,對於程序不能被長時間打斷的實時環境特別適合,另外,收集過程也有助於改進引用局部性。

缺點:(1).無法處理循環引用的問題既兩個或多個對象之間相互引用,因爲它們的引用計數永遠不會爲0。(2).每次增減引用計數都帶來額外開銷,而且該算法還需要編譯器的高度配合。

2).標記-清除(Mark-Sweep)

說明:垃圾收集過程執行分兩階段。在標記階段,垃圾收集器遍歷引用樹,標記每一個遇到的對象。在清理階段,未被標記的對象被釋放,相應內存被返還待用,此算法需要暫停整個應用。

優點:可以輕易回收循環結構,而且不存在爲維護引用計數而付出的額外開銷和對編譯器的依賴。

缺點:(1).在清理階段,堆中的所有對象,不論是否可達,都會被訪問。一方面這對於可能有頁面交換的堆所依賴的虛存系統有着非常負面的性能影響;另一方面,因爲其中很大一部分對象可能是垃圾,這就意味着垃圾收集器把大量精力都花費在檢查和處理垃圾上面了。無論從哪個角度來看,該算法都可能產生收集暫停時間過長、收集開銷偏大的問題。(2).標記並清理收集器的另一個不足是它容易導致堆的碎片化,從而引發引用局部性或者大對象分配失敗等方面的問題。

3).標記-整理(Mark-Compact)

說明:標記並清理收集器結合了"標記-清除"和"複製"兩個算法的優點,分爲兩個階段,第一階段從根節點開始標記所有被引用對象,第二階段遍歷整個堆,把清除未標記對象並且把存活對象"壓縮"到堆的其中一塊,按順序排放。

優點:此算法避免了"標記-清除"算法的碎片問題,同時也避免了"複製"算法的空間問題。

4).複製(Copying)

說明:複製的收集算法將可用內存按容量劃分爲大小相等的兩塊,每次只是用其中一塊。當這一塊的內存用完了,就將還存活着的對象複製到另外一塊上面,然後再把已使用過的內存空間一次清理掉。

優點:複製的收集算法每次都是對其中的一塊進行內存回收,沒存分配時也就不用考慮內存碎片等複雜情況,只要移動堆頂指針,按順序分配內存即可,實現簡單,運行高效。

缺點:需要兩倍內存空間。

(2).分區對待方式

1).增量收集(Incremental Collecting)

說明:實時垃圾回收算法,即在應用進行的同時進行垃圾回收。

2).分代收集(Generational Collecting)

說明:基於對對象生命週期分析後得出的垃圾回收算法。把對象分爲新生代、老年代、持久代,對不同生命週期的對象使用不同的算法進行回收。

備註:在新生代中,每次垃圾收集時都發現有大批對象死去,只有少量存活,那麼就選用複製算法,只需要付出少量存活對象的複製成本就可以完成收集。而老年代中因爲對象存活率高、沒有額外空間對它進行分配擔保,就必須使用標記-清理或標記-整理算法來進行回收。

(3).系統線程

1).串行收集

說明:串行收集使用單線程處理所有垃圾回收工作。

優點:無需多線程交互,實現容易,而且效率比較高。

缺點:會產生系統停頓,單線程。

適用情況:數據量比較小(100M左右),單處理器下並且對響應時間無要求的應用。

2).並行收集

說明:並行收集使用多線程處理垃圾回收工作。

優點:速度快,效率高,理論上CPU數目越多,越能體現出並行收集器的優勢。

缺點:會產生系統停頓,多線程,可以限制線程數量。

適用情況:"對吞吐量有高要求",多CPU、對應用響應時間無要求的中、大型應用。舉例:後臺處理、科學計算。

3).併發收集

說明:可以保證大部分工作都併發進行(應用不停止),垃圾回收只暫停很少的時間。

優點:不會產生系統停頓,多線程,可以一個線程也可以和應用程序一起組成多線程。

適用情況:"對響應時間有高要求",多CPU、對應用響應時間有較高要求的中、大型應用。舉例:Web服務器/應用服務器、電信交換、集成開發環境。

發佈了46 篇原創文章 · 獲贊 40 · 訪問量 27萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章