IDEA是個好東西变抽,可以說是地球上最好的Java開發(fā)工具础拨,但是偶爾也會卡頓,仔細(xì)想想IDEA也是Java開發(fā)的瞬沦,會不會和GC有關(guān)太伊,于是就有了接下來對IDEA的GC進(jìn)行調(diào)優(yōu);
IDEA默認(rèn)JVM參數(shù):
-Xms128m
-Xmx750m
-XX:MaxPermSize=350m
-XX:ReservedCodeCacheSize=240m
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
第一次優(yōu)化
以默認(rèn)參數(shù)啟動完成后逛钻,利用jstat -gcutil pid 3s 查看GC情況:
圖中反應(yīng)出了1個非常明顯的問題:Old區(qū)會擴(kuò)容僚焦。這是因?yàn)閄ms和Xmx值不一致引起的;所以對JVM參數(shù)的第一個優(yōu)化點(diǎn)就是Xms和Xmx曙痘;
第一次優(yōu)化后的JVM參數(shù)為:
-Xms1024m
-Xmx1024m
-Xmn372m
-XX:MaxPermSize=350m
-XX:ReservedCodeCacheSize=240m
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
第二次優(yōu)化
經(jīng)過第一次優(yōu)化后芳悲,再次啟動IDEA,得到如下的GC日志:
很明顯Metaspace會出現(xiàn)擴(kuò)容的情況边坤,所以第二次優(yōu)化點(diǎn)為:-XX:MetaspaceSize和-XX:MaxMetaspaceSize
第二次優(yōu)化后的JVM參數(shù)為:
-Xms1024m
-Xmx1024m
-Xmn372m
-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=512m
-XX:ReservedCodeCacheSize=240m
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
說明:由于我用的是JDK8名扛,所以刪除了參數(shù)-XX:MaxPermSize=350m,取而代之的是-XX:MetaspaceSize=256m和-XX:MaxMetaspaceSize=512m茧痒,如果讀者你用的是JDK7及以前的版本肮韧,那么請用-XX:PermSize=256m和-XX:MaxPermSize=512m
總結(jié)
經(jīng)過第二次優(yōu)化后,啟動IDEA的GC情況如下:
由圖所示, GC情況比較健康了旺订,沒有FGC东涡,且GCT有明顯的下降芜壁,唯一的缺陷就是YGC的平均耗時過長,這是由于我的電腦配置較低,CPU是雙核心的緣故掀潮,一般生產(chǎn)環(huán)境Linux服務(wù)器上YGC的時間是幾十毫秒級別米辐,超過100ms就要注意排查是否有問題了洪己;
寫在最后
加上幾個經(jīng)驗(yàn)參數(shù),最終的JVM參數(shù)如下:
-Xms1024m
-Xmx1024m
-Xmn372m
-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=512m
-XX:ReservedCodeCacheSize=240m
-XX:+UseConcMarkSweepGC
-XX:+UseParNewGC
-XX:+CMSParallelRemarkEnabled
-XX:+CMSScavengeBeforeRemark
-XX:CMSInitiatingOccupancyFraction=75
-XX:+UseCMSInitiatingOccupancyOnly
-XX:+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction=3
-XX:SoftRefLRUPolicyMSPerMB=50
說明:
- -XX:+UseParNewGC:顯示聲明Young區(qū)垃圾回收算法届良,也可以不顯示聲明(顯示聲明為了讓JVM參數(shù)更易懂),因?yàn)镺ld區(qū)申明為CMS GC的話圣猎,Young區(qū)默認(rèn)就是ParNew士葫;
- -XX:+CMSParallelRemarkEnabled:CMS的remark階段多線程并行;該參數(shù)默認(rèn)就是true样漆,所以這里只是顯示聲明为障;
- -XX:+CMSScavengeBeforeRemark:CMS GC前執(zhí)行一次Minor GC,即YGC放祟;
- -XX:CMSInitiatingOccupancyFraction=75:如果Old區(qū)聲明為CMS GC的話鳍怨,該參數(shù)的默認(rèn)值為92,比較大跪妥,建議調(diào)小到75鞋喇,減少Promotion failed的概率;
- -XX:+UseCMSInitiatingOccupancyOnly:只有當(dāng)Old區(qū)達(dá)到75%時才觸發(fā)CMS GC眉撵,如果不聲明的話侦香,還有很多種其他條件觸發(fā)CMS GC;
- -XX:+UseCMSCompactAtFullCollection:CMS是標(biāo)記清理算法纽疟,每次回收后有內(nèi)存碎片問題罐韩,該參數(shù)會整理內(nèi)存碎片,但是會影響暫停時間污朽;
- -XX:CMSFullGCsBeforeCompaction=3:表示經(jīng)過多少次foreground CMS GC后對Old區(qū)做一次壓縮散吵。由于UseCMSCompactAtFullCollection這個參數(shù)為true整理內(nèi)存碎片時會影響性能,但是碎片問題也需要解決或者緩解蟆肆。所以矾睦,設(shè)置適當(dāng)調(diào)整該參數(shù)的值,在執(zhí)行多次foreground CMS GC后才對Old區(qū)進(jìn)行壓縮炎功;
寫在最后:我們常說的CMS GC是Backgroud CMS GC, 會經(jīng)歷我們熟知的5個階段: 初始化標(biāo)記->并行標(biāo)記->重新標(biāo)記->并行清理->并行重置枚冗。而foreground CMS GC被觸發(fā)時,會停止所有的java線程蛇损,同時終止Backgroud CMS GC赁温,串行回收Old區(qū)的垃圾,對系統(tǒng)吞吐量和性能影響非常大淤齐;