jdk8垃圾收集器

     垃圾收集器是垃圾回收算法(標記-清除算法、複製算法、標記-整理算法)的具體實現,不同商家、不同版本的JVM所提供的垃圾收集器可能會有很在差別.

è¿éåå¾çæè¿°

1.  圖中展示了7種不同分代的收集器:

     Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS、G1;

2.  而它們所處區域,則表明其是屬於新生代收集器還是老年代收集器:

    新生代收集器:Serial、ParNew、Parallel Scavenge;

    老年代收集器:Serial Old、Parallel Old、CMS;

    整堆收集器:G1;

3.  兩個收集器間有連線,表明它們可以搭配使用:

      Serial/Serial Old、Serial/CMS、ParNew/Serial Old、ParNew/CMS、Parallel Scavenge/Serial Old、Parallel             Scavenge/Parallel Old、G1;
 

Serial收集器

è¿éåå¾çæè¿°

Serial收集器是單線程收集器,是分代收集器。它進行垃圾收集時,必須暫停其他所有的工作線程,直到它收集結束(Stop TheWorld)。

1. 新生代:單線程複製收集算法;
2. 老年代:單線程標記整理算法。


Serial一般在單核的機器上使用,是Java 5非服務端JVM的默認收集器,參數-XX:UseSerialGC設置使用。
優勢:對於單CPU環境來說,Serial收集器沒有線程交互的開銷,專心做垃圾收集可以獲得最高的單線程收集。Serial收集器對於在Client模式下的虛擬機是一個很好的選擇。
 

ParNew收集器

è¿éåå¾çæè¿°

ParNew收集器其實就是Serial收集器的多線程版本。新生代並行,老年代串行;新生代複製算法、老年代標記-整理

參數控制:
-XX:+UseConcMarkSweepGC":指定使用CMS後,會默認使用ParNew作爲新生代收集器;
-XX:+UseParNewGC":強制指定使用ParNew;
-XX:ParallelGCThreads":指定垃圾收集的線程數量,ParNew默認開啓的收集線程與CPU的數量相同;

優勢:ParNew收集器是許多運行在server模式下的虛擬機中首選的新生代收集器,一個重要的原因是,只有ParNew和Serial收集器能和CMS收集器共同工作。無法與JDK1.4中存在的新生代收集器Parallel Scavenge配合工作,所以在JDK1.5中使用CMS來收集老年代的時候,新生代只能選擇ParNew和Serial。

ParNew收集器在單CPU環境中不比Serial效果好,甚至可能更差,兩個CPU也不一定跑的過,但隨着CPU數量的增加,性能會逐步增加。默認開啓的收集線程數與CPU數量相同。在CPU數量很多的情況下,可以使用-XX:ParallelGCThreads參數來限制線程數。

 

Parallel Scavenge收集器

Parallel Scavenge收集器是一個新生代的手機器,使用的是複製算法的收集器,而且也是多線程的收集器。
Parallel Scavenge收集器,目標達到一個可控制的吞吐量,使用-XX:MaxGCPauseMillus參數控制垃圾停頓時間,使用-XX:GCTimeRatio參數控制吞吐量。Parallel Scavenge收集器設置-XX:UseAdaptiveSizePolicy參數,虛擬機會根據當前系統的運行情況收集性能監控信息,動態調整這些參數以提供最合適的停頓時間或者最大吞吐量(GC自使用的調節策略)。
自適應調節策略也是Parallel Scavenge收集器和ParNew收集器一個重要的區別。

 

Serial Old收集器

Serial收集器的老年代版,它同樣是一個單線程收集器,使用標記–整理算法。收集器的意義在於給Client模式下的虛擬機使用。如果在Server模式下,那麼它主要有兩大用途:一種是在jdk1.5以及之前的版本中與Parallel Scavenge收集器搭配使用,另一種用途是作爲CMS收集器的後預案,在併發收集發生Concurrent Mode Failure時使用。工作流程圖如下:

è¿éåå¾çæè¿°

Parallel Old 收集器

Parallel Scavenge收集器的老年代版,使用多線程與標記–整理算法。這個收集器在jdk1.6中才開始提供的,直到Parallel Old 收集器出現後,“吞吐量優先”收集器終於有了比較名副其實的應用組合,在注重吞吐量以及CPU資源敏感的場合,都可以優先考慮Parallel Scavenge加 Parallel Old收集器
è¿éåå¾çæè¿°

CMS收集器

一種以獲取最短回收停頓時間爲目標的收集器。目前很大一部分的java應用集中在互聯網站或者B/S系統的服務端上,這類應用尤其重視服務的響應速度,希望系統停頓時間最短,以給用戶帶來較好的體驗。CMS收集器就非常符合這類應用的需求。CMS收集器是基於“標記-清除”算法實現的,主要分爲4個步驟。
 

1. 初始標記(CMS inital mark):需要“stop the world”,但只標記一下GC Roots能直接關聯的對象,速度很快。
2. 併發標記(CMS concurrent mark):是GC Roots Tracing的過程,花費時間長
3. 重新標記(CMS remark):*需要“stop the world”,是爲了修正併發標記期間因用戶程序繼續運行而導致標記產生變動的那一部分對象的標記記錄,這個階段時間一般會比初始標記階段稍長一些,但遠比並發標記的時間短。
4. 併發清除(CMS concurrent sweep):是併發清除無用對象。
 

缺點:

1. CMS收集器對CPU資源非常敏感。在併發階段,它雖然不會導致用戶線程停頓,但是因爲佔用了一部分CPU資源而導致應用程序變慢,總吞吐量就會降低。CMS默認啓動的回收線程數爲(CPU數量+3)/4。當CPU的個數少於2個的時候,CMS對用戶程序的影響可能會變得很大。


2. CMS收集器無法處理浮動垃圾(floating garbage),可能會出現concurrent mode failure導致另一次full gc的產生。在CMS的併發清理階段,由於程序還在運行,垃圾還會不斷產生,這一部分垃圾出現在標記過程之後,CMS無法在本次收集中處理掉它們,只好留到下一次GC再處理。這種垃圾稱爲浮動垃圾。同樣由於CMS GC階段用戶線程還需要運行,即還需要預留足夠的內存空間供用戶線程使用,因此CMS收集器不能像其他收集器那樣等到老年代幾乎完全被灌滿了再進行收集而需要預留一部分空間提供併發收集時的程序運作使用。默認設置下 CMS收集器在老年代使用了68%的空間後就會被激活。這個值可以用-XX:CMSInitiatingOccupancyFraction來設置。要是CMS運行期間預留的內存無法滿足程序需要,就會出現concurrent mode failure,這時候就會啓用Serial Old收集器作爲備用進行老年代的垃圾收集。


3. 空間碎片過多(標記-清除算法的弊端),CMS是基於標記-清除算法來實現的回收器,提供-XX:+UseCMSCompactAtFullCollection參數,應用於在FULL GC後再進行一個碎片整理過程。-XX:CMSFullGCsBeforeCompaction,多少次不壓縮的full gc後來一次帶壓縮的。
 

G1收集器

G1收集器(Garbage-First):是當今收集器技術發展的最前沿的成果之一,G1是一款面向服務器端應用的垃圾收集器。 使用G1收集器時,java堆的內存佈局就與其他收集器有很大差別,它將真個java堆劃分爲多個大小相等的獨立區域(Region),雖然還保留新生代與老年代的概念,但新生代與老年代不再試物理隔離的了,他們都是一部分Region(不需要連續)的集合。G1具備如下特點:


1. 並行與併發:G1能充分利用多CPU、多核環境下的硬件優勢,使用多個CPU(CPU或者CPU核心)來縮短Stop-The-World停頓的時間,部分其他收集器原本需要停頓java線程執行的GC動作,G1收集器仍然可以通過併發的方式讓java程序繼續執行。


2. 分代收集:與其他收集器一樣,分代概念在G1中依然得以保留。雖然G1可以不需要其他收集器配合就能夠獨立管理整個GC堆,但它能夠採用不同的方式去處理新創建的對象和已經存活了一段時間、熬過多次GC的舊對象以獲取更好的收集效果。


3. 空間整合:與CMS的“標記–清理”算法不同,G1從整體來看是基於“標記–整理”算法實現的收集器,從局部(兩個Region之間)上來看是基於“複製”算法實現的,但無論如何,這兩種算法都意味着G1運行期間不會產生內存空間碎片,收集後能提供規整的可用內存。這個特性有利於程序長時間運行,分配大對象時不會因爲無法找到連續內存空間而提前出發下一次GC。


4. 可預測的停頓:這是G1相對於CMS的另一大優勢,降低停頓時間是G1和CMS共同的關注點,但G1除了追求低停頓外,還能建立可預測的停頓時間模型,能讓使用者明確指定在一個長度爲M毫秒的時間片段內,消耗在垃圾收集上的時間不得超過N毫秒,這幾乎已經是實時java(RTSJ)的垃圾收集器的特性了。


5. 初始標記(Initial Marking):標記GC Roots能夠直接關聯到的對象,並且修改TAMS的值,能在正確可用的Region中創建對象,這階段需要停頓線程,而且耗時很短。


6. 併發標記(Concurrent Marking):從GC Roots開始堆中對象進行可達性分析,找出存活的對象,這個時間耗時比較長,但可與用戶程序並行執行。


7. 最終標記(Final Marking):爲了修正和正在併發標記期間因用戶程序繼續運行而導致標記產生變動的那一部分沒有標記記錄,虛擬機將這一段對象變法記錄在線程Rememberred Set logs裏面,最終標記階段需要把Remembered Set logs 的數據合併到Remembered Set中,這階段需要停頓線程,但是可併發執行。


8. 篩選回收(Live Data Counting and Evacuation):對各個Region的回收截止和成本進行排序,根據用戶期望的GC停頓時間來制定回收計劃,這階段可以做到和用戶程序一起併發執行,但是因爲值回收一部分Region,時間是用戶可控制的,而且停頓用戶線程將大幅度提高手機效率。
 

è¿éåå¾çæè¿°

 

Minor GC和Full GC的區別

(A)、Minor GC
又稱新生代GC,指發生在新生代的垃圾收集動作;
因爲Java對象大多是朝生夕滅,所以Minor GC非常頻繁,一般回收速度也比較快;
(B)、Full GC
又稱Major GC或老年代GC,指發生在老年代的GC;
出現Full GC經常會伴隨至少一次的Minor GC(不是絕對,Parallel Sacvenge收集器就可以選擇設置Major GC策略);
Major GC速度一般比Minor GC慢10倍以上;
 

詳解 JVM Garbage First(G1) 垃圾收集器

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章