七種垃圾回收器類型
GC的約定參數
DefNew——Default New Generation
Tenured——Serial Old
ParNew——Parallel New Generation
PSYoungGen——Parallel Scavenge
ParOldGen——Parallel Old Generation
適用范圍:只需要掌握Server模式,Client模式基本不會用。
操作系統:32位windows不論硬件如何默認使用Client模式。32位其他OS,2G內存同時2個CPU以上用Server模式,低於該配置是Client模式。64位只有Server模式。
七大垃圾收集器
串行GC:Serial收集器(1:1)
串行收集器是最古老的,最穩定,效率高的收集器,只使用一個線程去回收但其進行垃圾回收過程中可能會產生較長的停頓。雖然在收集垃圾的過程中需要暫停其他的工作線程,但是簡單高效,對於單CPU環境來說,沒有線程交互的開銷可以獲得最高的單線程垃圾收集效率,因此Serial垃圾回收器依然是Java虛擬機運行在Client模式下默認的新生代垃圾回收器。
開啟串行收集器的JVM參數是-XX:+UseSerialGC。
開啟后會使用:Serial(Young區)+ Serial Old(Old區)的收集器組合。表示新生代、老年代都會使用串行回收收集器,新生代用復制算法,老年代用標記整理算法。
顯式激活垃圾回收器:
並行GC:ParNew(N:1)
使用多線程進行垃圾回收,在垃圾回收時,會暫停所有其他工作線程,直到GC結束。
ParNew時Serial收集器新生代的並行多線程版本,最常見的應用場景是配合老年代CMS GC工作,其余行為和Seria收集器完全一樣,ParNew垃圾收集器在垃圾收集過程中同樣要暫停所有其他的工作線程。它是很多JVM運行在Server模式下新生代的默認垃圾收集器。
開啟串行收集器的JVM參數是-XX:+UseParNewGC。
啟用ParNew收集器,只影響新生代的收集(新生代GC頻繁),不影響老年代。開啟參數后,會使用ParNew(Young區)+Serial(Old區)的收集器組合。新生代使用復制算法,老年代使用標記整理算法。
ParNew+Tenured(Serial Old)不再推薦使用:
並行回收:Parallel Scavenge(N:N)
Parallel Scavenge收集器類似ParNew,也是一個新生代垃圾收集器,使用復制算法,也是一個並行的多線程的垃圾收集器,俗稱吞吐量優先收集器。相當於是串行收集器在新生代和老年代的並行化。
它重點關注可控制吞吐量,高吞吐量意味着高效利用CPU時間,它多用於在后台運算而不需要太多交互的任務。【吞吐量 = 用戶代碼運行時間/(用戶代碼運行時間+垃圾回收時間)】
自適應調節策略也是Parallel Scavenge收集器與ParNew收集器的一個重要區別。自適應調節策略就是JVM會根據當前系統的運行情況看收集性能監控信息,動態調整這些參數以提供最合適的停頓時間(-XX: MaxGCPauseMills)或最大吞吐量。
常用的JVM參數:-XX:+UseParallelGC 或者 +UseParallelOldGC(二者可以互相激活),使用Parallel Scavenge收集器。開啟參數后,新生代用復制算法,老年代用復制標記整理算法。
參數-XX:+ParallelGCThread = K 表示啟動K個GC線程【CPU > 8 K = 5或8 CPU < 8 K = 實際個數】
Parallel Old收集器
Parallel Old收集器是Parallel Scavenge收集器的老年代版本,使用多線程的標記整理算法,在JDK1.6開始提供。
JDK1.6之前,新生代使用Parallel Scavenge收集器只能搭配老年代Serial Old收集器,只能保證新生代的吞吐量優先,無法保證整體的吞吐量。在JDK1.6之前,是Parallel Scavenge+Serial Old。
Parallel Old是為了老年代同樣提供吞吐量優先的垃圾收集器,如果系統對吞吐量要求較高,JDK1.8后優先考慮新生代Parallel Scavenge和老年代 Parallel Old的搭配策列。在JDK1.8及之后,是Parallel Scavenge+Parallel Old。
JVM常用參數:-XX:+UseParallelOldGC使用Parallel Old收集器。和上一個part的截圖是一致的,UseParallelGC和UseParallelOldGC可以互相激活。
並發標記清除GC(CMS)
CMS收集器是一個以獲取最短回收停頓時間為目標的收集器。適合應用在互聯網站或BS系統的服務器上,因為這類場景重視服務器的響應速度,希望系統的停頓時間盡可能短。CMS適合堆內存大、CPU核數多的服務器端應用,也是G1出現之前大型應用的首選收集器。
CMS的優勢是並發收集停頓少,並發是指與用戶線程一起執行。
開啟收集器的JVM參數:-XX:+UseConcMarkSweepGC 開啟后會自動開啟 -XX:+UseParNewGC
並發標記清除收集器的組合:ParNew + CMS + Serial Old(作為CMS出錯的后備收集器,增強健壯性)
CMS內存回收一共有4個過程:
- 初始標記:只有標記一下GC Roots能直接關聯的對象,速度很快,仍然需要暫停所有的工作線程。
- 並發標記:進行GC Roots跟蹤的過程,和用戶線程一起工作,不需要暫停工作線程,主要標記過程,標記全部對象。
- 重新標記:修正在並發標記期間,因用戶程序繼續運行而導致標記產生變動的那一部分對象的標記記錄,仍然需要暫停所有的工作線程。由於並發標記時,用戶線程依然運行,因此在正式清理前再做修正。
- 並發清除:清除GC Roots不可達對象,和用戶線程一起工作,不需要暫停工作線程。基於標記結果,直接清理對象。由於耗時最長的並發標記和並發清除過程中,垃圾收集線程可以和用戶線程一起並發工作。所以總體上說CMS收集器的內存回收和用戶線程是並發執行的(初始標記和重新標記雖然要暫停,但是用時很短)。
優點:並發收集,停頓次數少。
缺點:對CPU的壓力大,CMS在收集和應用線程會同時增加對堆內存的占用,也就是i說CMS必須在老年代堆內存用完之前完成GC,否則CMS會回收失敗,將觸發擔保機制,Serial Old會以STW(Stop The World,暫停所有工作線程)的方式進行依次GC,從而造成較大的停頓時間。而且采用標記清除算法會產生內存碎片。
Serial Old收集器
Serial Old收集器是Serial垃圾收集器老年代版本,同樣是單線程的收集器,使用標記整理算法。
主要運行在Client默認的JVM老年代垃圾回收器。
在Server模式下,主要有兩個用途:
- 在JDK1.5之前與新生代Parallel Scavenge收集器搭配使用。(Parallel Scavenge+Serial Old)
- 作為老年代版中使用CMS收集器的后備垃圾回收方案。
G1垃圾回收器
內容較多,見【JVM】垃圾回收器總結(3)