JVM調優-CMS常見引數、執行緒計算與推薦配置
常見引數列表
-XX:+UseConcMarkSweepGC
開啟CMS GC收集器。JVM在1。8之前預設使用的是Parallel GC,9以後使用G1 GC。
-XX:UseParNewGC
當使用CMS收集器時,預設年輕代使用多執行緒並行執行垃圾回收(UseConcMarkSweepGC開啟後則預設開啟)。
-XX:+CMSParallelRemarkEnabled
採用並行標記方式降低停頓(預設開啟)。
-XX:+CMSConcurrentMTEnabled
被啟用時,併發的CMS階段將以多執行緒執行(因此,多個GC執行緒會與所有的應用程式執行緒並行工作)。(預設開啟)
-XX:ConcGCThreads
定義併發CMS過程執行時的執行緒數。
-XX:ParallelGCThreads
定義CMS過程並行收集的執行緒數。
-XX:CMSInitiatingOccupancyFraction
該值代表老年代堆空間的使用率,預設值為68。當老年代使用率達到此值之後,並行收集器便開始進行垃圾收集,該引數需要配合UseCMSInitiatingOccupancyOnly一起使用,單獨設定無效。
-XX:+UseCMSInitiatingOccupancyOnly
該引數啟用後,引數CMSInitiatingOccupancyFraction才會生效。預設關閉。
-XX:+CMSClassUnloadingEnabled
相對於並行收集器,CMS收集器預設不會對永久代進行垃圾回收。如果希望對永久代進行垃圾回收,可用設定-XX:+CMSClassUnloadingEnabled。預設關閉。
-XX:+CMSIncrementalMode
開啟CMS收集器的增量模式。增量模式使得回收過程更長,但是暫停時間往往更短。預設關閉。
-XX:CMSFullGCsBeforeCompaction
設定在執行多少次Full GC後對記憶體空間進行壓縮整理,預設值0。
-XX:+CMSScavengeBeforeRemark
在cms gc remark之前做一次ygc,減少gc roots掃描的物件數,從而提高remark的效率,預設關閉。
-XX:+ExplicitGCInvokesConcurrent
該引數啟用後JVM無論什麼時候呼叫系統GC,都執行CMS GC,而不是Full GC。
-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses
該引數保證當有系統GC呼叫時,永久代也被包括進CMS垃圾回收的範圍內。
-XX:+DisableExplicitGC
該引數將使JVM完全忽略系統的GC呼叫(不管使用的收集器是什麼型別)。
-XX:+UseCompressedOops
這個引數用於對類物件資料進行壓縮處理,提高記憶體利用率。(預設開啟)
-XX:MaxGCPauseMillis=200
這個引數用於設定GC暫停等待時間,單位為毫秒,不要設定過低。
CMS的執行緒數計算公式
區分young區的parnew gc執行緒數和old區的cms執行緒數,分別為以下兩引數:
-XX:ParallelGCThreads=m // STW暫停時使用的GC執行緒數,一般用滿CPU
-XX:ConcGCThreads=n // GC執行緒和業務執行緒併發執行時使用的GC執行緒數,一般較小
ParallelGCThreads
其中ParallelGCThreads 引數的預設值是:
CPU核心數 <= 8,則為 ParallelGCThreads=CPU核心數,比如我的那個舊電腦是4
CPU核心數 > 8,則為 ParallelGCThreads = CPU核心數 * 5/8 + 3 向下取整
16核的情況下,ParallelGCThreads = 13
32核的情況下,ParallelGCThreads = 23
64核的情況下,ParallelGCThreads = 43
72核的情況下,ParallelGCThreads = 48
ConcGCThreads
ConcGCThreads的預設值則為:
ConcGCThreads = (ParallelGCThreads + 3)/4 向下去整。
ParallelGCThreads = 1~4時,ConcGCThreads = 1
ParallelGCThreads = 5~8時,ConcGCThreads = 2
ParallelGCThreads = 13~16時,ConcGCThreads = 4
推薦配置
8C16G下的引數配置
綜上所述,8C16G下,推薦使用如下的引數設定:
-Xmx12g -Xms12g
-XX:ParallelGCThreads=8
-XX:ConcGCThreads=2
-XX:+UseConcMarkSweepGC
-XX:+CMSClassUnloadingEnabled
-XX:+CMSIncrementalMode
-XX:+CMSScavengeBeforeRemark
-XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSInitiatingOccupancyFraction=70
-XX:CMSFullGCsBeforeCompaction=5
-XX:MaxGCPauseMillis=100 // 按業務情況來定
-XX:+ExplicitGCInvokesConcurrent
-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses
-XX:+PrintGCTimeStamps
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
4C8G下的引數配置
如果是4C8G配置下,推薦
-Xmx6g -Xms6g
-XX:ParallelGCThreads=4
-XX:ConcGCThreads=1
// 其他不變。。。。
2C4G下的引數配置
如果是2C4G配置下,推薦
-Xmx3g -Xms3g
-XX:ParallelGCThreads=2
-XX:ConcGCThreads=1
// 其他不變。。。。
留一個小技巧讓大家猜一猜:為什麼最大堆記憶體配置,不建議跟容器/虛擬機器記憶體一樣,比如8G的ECS雲主機,直接配置 -Xmx8g??(後續的文章裡,會跟大家分析。)