JVM介紹
收集器
常見收集器如:Serial收集器、Serial Old收集器、ParNew收集器、Parallel Scavenge收集器、Parallel Old收集器、CMS收集器、G1收集器
Serial收集器
Serial收集器是最基本的,發展歷史最悠久的收集器。在JDK1.3之前是虛擬機新生代收集的唯一選擇。是一種單線程收集器,只會使用一個CPU或者一條收集線程去完成垃圾收集工作,在進行垃圾收集的時候需要暫停其他線程
- 優點:簡單高效,很高的單線程收集效率
- 缺點:收集過程需要暫停所有線程
- 算法:復制算法
- 使用范圍:新生代
- 應用:client模式下的默認新生代收集器
Serial Old收集器
Serial Old收集器是Serial收集器的老年代版本,是一個單線程收集器,不同的采用標記-整理算法,運行過程和Serial收集器一樣。
ParNew
可以理解為Serial收集器的多線程版本
- 優點:在多CPU時,比Serial效率高
- 缺點:收集過程暫停所有應用程序線程,單CPU時比Serial效率差
- 算法:復制算法
- 使用范圍:新生代
- 應用:運行在server模式下的虛擬機中首選的新生代收集器
Parallel Scavenge
Parallel Scavenge收集器是一個新生代收集器。使用復制算法,并行的多線程收集器。與ParNew不同的是更關注系統的吞吐量
吞吐量=運行用戶代碼的時間/(運行用戶代碼時間+垃圾收集時間)
如虛擬機總共運行了100分鐘,垃圾收集用了1分鐘吞吐量=(100-1)/100=99%
若吞吐量越大,意味著垃圾收集的時間越短,則用戶代碼可以充分利用CPU資源,盡快完成程序的運算任務。
-XX:MaxGCPauseMillis控制最大的垃圾收集停頓時間
-XX:GCRatio直接設置吞吐量的大小
Parallel Old
Parallel Old收集器是Parallel Scavenge收集器的老年代版本,使用多線程標記-整理算法進行垃圾回收,更加關注系統的吞吐量
CMS收集器
Concurrent Mark Sweep收集器是一種以獲取最短回收停頓時間為目標的收集器。CMS采用 標記-清理 的算法,標記出垃圾對象,清除垃圾對象。算法是基于老年代執行的,因為新生代產生無法接受該算法產生的碎片垃圾。可以配合新生代的Serial和ParNew收集器一起使用
- 優點:并發收集,低停頓
- 不足:無法處理浮動垃圾,并發收集會造成內存碎片過多; CPU資源非常敏感,在并發階段雖然不會導致用戶線程停頓,但是會因為占用了一部分CPU資源,如果在CPU資源不足的情況下應用會有明顯的卡頓。
采用的是標記-清除算法整個過程分為4步:
- 初始標記階段:會讓線程全部停止,也就是 Stop the World 狀態
- 并發標記階段:對所有的對象進行追蹤,這個階段最耗費時。但這個階段是和系統并發運行的,所以不會對系統運行造成影響
- 重新標記階段:由于第二階段是并發執行的,一邊標記垃圾對象,一邊創建新對象,老對象會變成垃圾對象。 所以第三階段也會進入 Stop the World 狀態,并且重新標記,標記的是第二階段中變動過的少數對象,所以運行速度很快
- 并發清理階段: 這個階段也是會耗費很多時間,但由于是并發運行的,所以對系統不會造成很大的影響。
G1收集器
G1收集器收集范圍是老年代和新生代。不需要結合其他收集器使用。
G1(Garbage-Frist) JDK8推薦使用的 比CMS的停頓時間短。優先回收垃圾價值高的區域,某種程度上解決空間碎片的問題。
- 初始標記(Initial Marking):僅僅只是標記一下GC Roots能直接關聯到的對象,并且修改TAMS指針的值,讓下一階段用戶線程并發運行時,能正確地在可用的Region中分配新對象。這個階段需要停頓線程,但耗時很短,而且是借用進行Minor GC的時候同步完成的,所以G1收集器在這個階段實際并沒有額外的停頓。
- 并發標記( Concurrent Marking):從GC Root開始對堆中對象進行可達性分析,遞歸掃描整個堆里的對象圖,找出要回收的對象,這階段耗時較長,但可與用戶程序并發執行。當對象圖掃
描完成以后,并發時有引用變動的對象會產生漏標問題,G1中會使用SATB(snapshot-at-the-beginning)算法來解決,后面會詳細介紹。 - 最終標記(Final Marking):對用戶線程做一個短暫的暫停,用于處理并發標記階段仍遺留下來的最后那少量的SATB記錄(漏標對象)。 多個線程同時標記
- 篩選回收(Live Data Counting and Evacuation):負責更新Region的統計數據,對各個Region的回收價值和成本進行排序,根據用戶所期望的停頓時間來制定回收計劃,可以自由選擇任意多個Region構成回收集,然后把決定回收的那一部分Region的存活對象復制到空的Region中,再清理掉整個舊Region的全部空間。這里的操作涉及存活對象的移動,是必須暫停用戶線程,由多個收集器線程并行完成的。
什么情況下應該考慮使用G1
參考官方文檔:
- 實時數據占用超過一半的堆空間
- 對象分配或者晉升的速度變化大
- 希望消除長時間的GC停頓(超過0.5-1秒)
G1設置參數
控制G1回收垃圾的時間
-XX:MaxGCPauseMillis=200 (默認200ms)
來源:
JVM垃圾收集器知識 (baidu.com)
CMS收集器和G1收集器的區別g1和cms的區別技術無產者的博客-CSDN博客