Stop The World:不管選擇哪種GC算法,stop-the-world都是不可避免的。Stop-the-world意味著從應用中停下來并進入到GC執(zhí)行過程中去。一旦Stop-the-world發(fā)生,除了GC所需的線程外,其他線程都將停止工作,中斷了線程直到GC任務結束才繼續(xù)它們的任務。GC調優(yōu)通常就是為了改善stop-the-world的時間。


CMS收集器

一種以獲取最短回收停頓時間為目標的收集器,CMS收集器是基于"標記-清除"(mark-sweep)算法實現的。


整個過程分為四個步驟:

1. 初始標記 (Stop the World事件CPU停頓很短) 僅標記一下GC Roots能直接關聯到的對象,速度很快;

2. 并發(fā)標記 (收集垃圾跟用戶線程一起執(zhí)行) 初始標記和重新標記仍然需要“stop the world”,并發(fā)標記過程就是進行GC Roots Tracing的過程;

3. 重新標記 (Stop the World事件 CPU停頓,比初始標記稍微長,遠比并發(fā)標記短)修正并發(fā)標記期間因用戶程序繼續(xù)運作而導致標記產生變動的那一部分對象的標記記錄,這個階段的停頓時間一般會比初始標記階段稍長一些,但遠比并發(fā)標記時間短

4. 并發(fā)清理 -清除算法;

  整個過程中耗時最長的并發(fā)標記和并發(fā)清除過程收集器線程都可以與用戶線程一起工作,所以,從總體上來說,CMS收集器的內存回收過程是與用戶線程一起并發(fā)執(zhí)行的。

優(yōu)點

1.并發(fā)收集

2.低停頓

缺點

1.CMS收集器對CPU資源非常敏感

在并發(fā)階段,雖然不會導致用戶線程停頓,但是會因為占用了一部分線程使應用程序變慢,總吞吐量會降低,為了解決這種情況,虛擬機提供了一種“增量式并發(fā)收集器”的CMS收集器變種,就是在并發(fā)標記和并發(fā)清除的時候讓GC線程和用戶線程交替運行,盡量減少GC 線程獨占資源的時間,這樣整個垃圾收集的過程會變長,但是對用戶程序的影響會減少。(效果不明顯,不推薦)

2.CMS處理器無法處理浮動垃圾

CMS在并發(fā)清理階段線程還在運行,伴隨著程序的運行自然也會產生新的垃圾,這一部分垃圾產生在標記過程之后,CMS無法再當次過程中處理,所以只有等到下次gc時候在清理掉,這一部分垃圾就稱作“浮動垃圾” ,

3.CMS是基于“標記--清除”算法實現的,所以在收集結束的時候會有大量的空間碎片產生。空間碎片太多的時候,將會給大對象的分配帶來很大的麻煩,往往會出現老年代還有很大的空間剩余,但是無法找到足夠大的連續(xù)空間來分配當前對象的,只能提前觸發(fā) full gc。 為了解決這個問題,CMS提供了一個開關參數,用于在CMS頂不住要進行full gc的時候開啟內存碎片的合并整理過程,內存整理的過程是無法并發(fā)的,空間碎片沒有了,但是停頓的時間變長了。


G1(Garbage First)

優(yōu)先處理那些垃圾多的內存塊,G1只有并發(fā)標記才不會stop-the-world 其他都會停下來

步驟:

1、初始標記(stop the world事件 CPU停頓只處理垃圾);

2、并發(fā)標記(與用戶線程并發(fā)執(zhí)行);(不會觸發(fā)stop the world事件)

3、最終標記(stop the world事件 ,CPU停頓處理垃圾);

4、篩選回收(stop the world事件 根據用戶期望的GC停頓時間回收); (注意:CMS 在這一步不需要stop the world)

與其他GC收集器相比,G1具備如下特點:

1、并行于并發(fā):G1能充分利用CPU、多核環(huán)境下的硬件優(yōu)勢,使用多個CPU(CPU或者CPU核心)來縮短Stop-The-World停頓時間。部分其他收集器原本需要停頓??Java??線程執(zhí)行的GC動作,G1收集器仍然可以通過并發(fā)的方式讓java程序繼續(xù)執(zhí)行。

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

3、空間整合:與CMS的“標記--清理”算法不同,G1從整體來看是基于“標記-整理”算法實現的收集器;從局部上來看是基于“復制”算法實現的。

4、可預測的停頓:這是G1相對于CMS的另一個大優(yōu)勢,降低停頓時間是G1和CMS共同的關注點,但G1除了追求低停頓外,還能建立可預測的停頓時間模型,能讓使用者明確指定在一個長度為M毫秒的時間片段內。