Java垃圾收集器

Java HotSpot虛擬機目前主要提供了7種垃圾收集器,每個都有他們不同的優勢,它們之間互相合作,共同收集垃圾。


一,Serial收集器

1. 它是新生代收集器,是一個單線程收集器,在收集垃圾時,必須暫停 其他所有工作線程,直到它收集結束。

2. 它對于運行在Client模式下的虛擬機來說是一個很好的選擇。因為在Client模式下,停頓只要不頻繁發生,是可以接受的。

二,ParNew收集器

1. 是Serial收集器的多線程版本,在新生代收集階段,可以同時開啟多個線程對垃圾進行收集。同樣,收集階段會暫停其他工作線程。

2. 它是許多運行在Server模式下的虛擬機中首選的新生代收集器。


三,Parallel Scavenge收集器

1. 是一個新生代收集器,是一個并行的收集器。

2. 它的關注點是達到一個可控制的吞吐量(運行用戶代碼時間/(運行用戶代碼時間+垃圾收集時間))。

3. 它的自適應調節策略也是與ParNew收集器的一個重要區別。虛擬機會根據當前系統的運行情況動態調整參數提供最合適的停頓時間或者最大的吞吐量。

四,Serial Old收集器

1. 是Serial收集的老年代版本,同樣是一個單線程收集器。

2. 在老年代中使用標記-整理算法。


五,Parallel Old收集器

1. 是Parallel Scavenge收集器的老年代版本。

2. 使用多線程和標記-整理算法,在JDK1.6中才開始提供。


六,CMS收集器

1. CMS(Concurrent Mark Sweep)是一種以獲取最短回收停頓時間為目標的收集器。

2. 運作過程分為:初始標記+并發標記+重新標記+并發清除。

3. 初始標記和重新標記仍然需要停頓,但時間少。

4. 初始標記僅僅是標記一下GC Roots能直接關聯到的對象,速度很快。并發標記階段是進行GC Roots Tracing的過程,而重新標記則是為了修正并發標記期間因用戶程序繼續運行而導致標記產生變動的那一部分對象的標記記錄。

5. 整個過程耗時最長的是并發標記和并發清除,但這兩個階段是與用戶線程同時執行的。

6. 明顯的缺點:

1)CMS收集器對CPU資源非常敏感。會占用CPU時間。

2)CMS收集器無法處理浮動垃圾(在并發清理階段用戶線程會產生新的垃圾,這一部分垃圾在標記過后,無法在當次收集中處理它們,只好留到下一次GC時再清理,這就是浮動垃圾)。由于在并發收集時還需要提供空間供用戶線程使用,所以不能等到老年代完全填滿之后再收集,在JDK1.5下檔老年代使用68%的空間后就會被激活,在1.6下提升到92%。要是CMS運行期間預留的內存無法滿足程序需要,就會出現Concurrent Mode Failure失敗,這時就會啟動后備預案:臨時啟動Serial Old收集器重新進行老年代的垃圾收集,這就會導致停頓時間變長。

3)它是基于標記-清除,所以會產生大量碎片空間,所以提供了內存碎片整理的功能(參數設置),但因此停頓時間會變長。


七,G1收集器

1. G1(garbage-First)收集器是一款面向服務端應用的垃圾收集器,具有以下特點:

1)并行與并發:充分利用CPU資源,縮短停頓時間。

2)分代收集:不和其他收集器配合就能獨立管理GC堆。

3)空間整合:從整體上看,是基于標記-整理的。

4)可預測的停頓:除了追求低停頓外,還能建立可預測的停頓模型。

2. 它將整個Java堆劃分為多個大小相等的獨立區域(Region),保留新生代和老年代的概念,但不再是物理隔離的,都是一部分Region的集合。

3. 它跟蹤各個Region里面的垃圾堆積的價值大小(回收所獲取的空間大小以及回收所需要額時間經驗值),維護一個優先列表,每次根據允許的收集時間,優先回收價值最大的Region。

4. 當然,一個Region可能引用另外Region的對象,那么是否就需要全局掃描呢?G1收集器利用Remembered Set來避免全對掃描。每個Region都有與之對應的Remembered Set,他會記錄與其他Region之間的對象互引用。

5. 如果不計算維護Remembered Set的操作,G1收集器的步驟如下:

1)初始標記

2)并發標記

3)最終標記

4)篩選回收

6. 其實在篩選回收階段,也可以做到并發執行,只是因為只回收一部分Region,時間是用戶可控制的,而且停頓用戶線程將大幅度提高收集效率,所以目前大部分的情況下木有采用篩選回收階段并發執行。


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容