垃圾收集器詳解及參數配置
垃圾搜集器簡介
垃圾搜集器大致分為以下三類###
- 串行搜集器(serial collector):它只有一條GC線程,且就像前面說的,它在運行的時候需要暫停用戶程序(stop the world)。
- 並行搜集器(parallel collector):它有多條GC線程,且它也需要暫停用戶程序(stop the world)。
- 並發搜集器(concurrent collector):它有一條或多條GC線程,且它需要在部分階段暫停用戶程序(stop the world),部分階段與用戶程序並發執行。
hotspot中的垃圾搜集器
- 串行搜集器的實現:serial(用於新生代,采用
復制算法
)、serial old(用於年老代,采用標記/整理算法
) - 並行搜集器的實現:ParNew(用於新生代,采用
復制算法
)、Parallel Scavenge(用於新生代,采用復制算法
)、Parallel old(用於年老代,采用標記/整理算法
) - 並發搜集器的實現:concurrent mark sweep[CMS](用於年老代,采用
標記/清除算法
)
垃圾收集器詳解
JVM啟動的兩種模式
- client模式:開發時默認啟動模式
- server模式:使用-server強制開啟server模式,
兩者的主要區別:
- server模式下做了大量的優化工作。
- server模式下應用啟動較慢,但在長時間運行情況下,運行速度會越來越快。
- client模式啟動快,但不適合長時間運行。
搜集器詳解
名稱 | 算法 | 內存區域 | 執行方式 | 執行過程 | 特點 | 適用場景 | 開啟參數 |
---|---|---|---|---|---|---|---|
Serial Garbage Collector | 復制算法 | 針對新生代設計 | 單線程、串行 | 當新生代內存不夠用時,先暫停全部用戶程序,然后開啟一條GC線程使用復制算法對垃圾進行回收,這一過程中可能會有一些對象提升到年老代 | 由於單線程運行,且整個GC階段都要暫停用戶程序,因此會造成應用程序停頓時間較長,但對於小規模的程序來說,卻非常適合。 | 平時的開發與調試程序使用,以及桌面應用交互程序。 | -XX:+UseSerialGC(client模式默認值) |
Serial Old Garbage Collector | 標記/整理算法 | 針對年老代設計 | 單線程、串行 | 同Serial Garbage Collector | 同Serial Garbage Collector | 同Serial Garbage Collector | - |
ParNew Garbage Collector | 復制算法 | 針對新生代設計 | 多線程、並行 | 開啟若干條GC線程使用復制算法並行進行垃圾回收,這一過程中可能會有一些對象提升到年老代 | 有幾個處理器就會開幾個線程(不過線程數是可以使用參數-XX:ParallelGCThreads=
|
在中到大型的堆上,且系統處理器至少多於一個的情況。對於單個處理器來說,由於並行執行的開銷(比如同步),ParNew的性能將會低於serial搜集器。 | -XX:+UseParNewGC |
Parallel Scavenge Garbage Collector | 復制算法 | 針對新生代設計 | 並行 | 優先滿足最大停頓時間的目標,次之是吞吐量,最后才是新生代區域的最小值。 | 更精確的控制GC停頓時間以及吞吐量 | 適用場景 | 控制最大的停頓時間(使用-XX:MaxGCPauseMillis=
|
Parallel Old Garbage Collector | 標記/整理算法 | 年老代設計 | 並行搜集器 | - | 它是除了serial old以外唯一一個可以與parallel scavenge搭配工作的年老代搜集器 | - | -XX:-UseParallelOldGC |
Concurrent Mark Sweep Garbage Collector | 標記/清除算法 | 年老代 | - | - | 應用程序與GC線程一起工作 | - | - |
組合的威力
三種經典的組合
serial & serial old
client模式下默認的垃圾收集器組合,可通過-XX:+UseSerialGC
強制開啟。非常適合運行於客戶端PC的小型應用程序,或者桌面應用程序(比如swing編寫的用戶界面程序),以及我們平時的開發、調試、測試等。
開發、調試、測試共同的特點:
- 1、由於都是在PC上運行,因此配置一般不會太高,或者說處理器個數不會太多。
- 2、上面幾種情況的應用程序都不會運行太久。
- 3、規模不會太大,也就是說,堆相對較小,搜集起來也比較快,停頓時間會比較短。
Parallel Scavenge & Parallel Old
這個組合是server模式下的默認組合(JDK6或JDK6之后),使用-XX:+UseParallelGC
參數強制開啟。
適用於一些需要長期運行且對吞吐量有一定要求的后台程序。
運行於后台的程序都有以下特點:
- 1、系統配置較高,通常情況下至少四核(以目前的硬件水平為准)。
- 2、對吞吐量要求較高,或需要達到一定的量。
- 3、應用程序運行時間較長。
- 4、應用程序規模較大,一般是中到大型的堆。
ParNew & CMS(Serial Old作為替補)
它則是對響應時間(response time)要求較高的應用程序的首選,使用參數-XX:+UseConcMarkSweepGC
開啟。
新生代采用並行搜集器
適用於一些需要長期運行且對相應時間有一定要求的后台程序。
采用ParNew & CMS
組合的后台應用程序,一般都對相應時間有一定要求,最典型的就是我們的WEB應用程序
。
垃圾搜集器參數精解
垃圾搜集器選擇參數
名稱 | 說明 | 備注 |
---|---|---|
UseSerialGC | 開啟此參數使用serial & serial old搜集器(client模式默認值)。 | |
UseParNewGC | 開啟此參數使用ParNew & serial old搜集器(不推薦)。 | |
UseConcMarkSweepGC | 開啟此參數使用ParNew & CMS(serial old為替補)搜集器。 | |
UseParallelGC | 開啟此參數使用parallel scavenge & parallel old搜集器(server模式默認值)。 | |
UseParallelOldGC | 開啟此參數在年老代使用parallel old搜集器(該參數在JDK1.5之后已無用)。 |
JVM各個內存區域大小相關參數
名稱 | 說明 | 備注 |
---|---|---|
Xms | 堆的初始值。默認為物理內存的1/64,最大不超1G。 | |
Xmx | 堆的最大值。默認為物理內存的1/4,最大不超1G。 | |
Xmn | 新生代的大小。 | |
Xss | 線程棧大小。 | |
PermSize | 永久代初始大小。默認為物理內存的1/64,最大不超1G。 | |
MaxPermSize | 永久代最大值。默認為物理內存的1/4,最大不超1G。 | |
NewRatio | 新生代與年老代的比例。比如為3,則新生代占堆的1/4,年老代占3/4。 | |
SurvivorRatio | 新生代中調整eden區與survivor區的比例,默認為8,即eden區為80%的大小,兩個survivor分別為10%的大小。 |
垃圾搜集器性能通用參數
名稱 | 說明 | 備注 |
---|---|---|
PretenureSizeThreshold | 晉升年老代的對象大小。默認為0,比如設為10M,則超過10M的對象將不在eden區分配,而直接進入年老代。 | |
MaxTenuringThreshold | 晉升老年代的最大年齡。默認為15,比如設為10,則對象在10次普通GC后將會被放入年老代。 | |
DisableExplicitGC | 禁用System.gc()。 |
並行搜集器參數
名稱 | 說明 | 備注 |
---|---|---|
ParallelGCThreads | 回收時開啟的線程數。默認與CPU個數相等。 | |
GCTimeRatio | 設置系統的吞吐量。比如設為99,則GC時間比為1/1+99=1%,也就是要求吞吐量為99%。若無法滿足會縮小新生代大小。 | |
MaxGCPauseMillis | 設置垃圾回收的最大停頓時間。若無法滿足設置值,則會優先縮小新生代大小,仍無法滿足的話則會犧牲吞吐量。 |
並發搜集器參數
名稱 | 說明 | 備注 |
---|---|---|
CMSInitiatingOccupancyFraction | 觸發CMS收集器的內存比例。比如60%的意思就是說,當內存達到60%,就會開始進行CMS並發收集。 | |
UseCMSCompactAtFullCollection | 在每一次CMS收集器清理垃圾后送一次內存整理。 | |
CMSFullGCsBeforeCompaction | 設置在幾次CMS垃圾收集后,觸發一次內存整理。 |
整理自: