JVM GC調(diào)優(yōu)

目標(biāo)

滿足應(yīng)用的響應(yīng)時(shí)間和吞吐量需求,盡量減少GC對(duì)應(yīng)用的影響

原則

  1. 大部分時(shí)候都不需要調(diào)優(yōu)GC,只需配置-Xms,-Xmx即可,JVM會(huì)自動(dòng)進(jìn)行調(diào)整
  2. 先滿足響應(yīng)時(shí)間需求,再滿足吞吐量需求
  3. FullGC對(duì)應(yīng)用的影響更大,要盡量減少FullGC執(zhí)行的時(shí)間和頻率,減少轉(zhuǎn)移到Old的對(duì)象數(shù)量

監(jiān)控GC狀態(tài)

  • 查看一下GC的總體執(zhí)行情況
jstat -gcutil pid
參數(shù) 說(shuō)明
YGC Minor GC執(zhí)行的次數(shù)
YGCT Minor GC執(zhí)行的總耗時(shí)
YGCT/YGC Minor GC平均耗時(shí)
FGC Full GC執(zhí)行的次數(shù)
FGCT Full GC執(zhí)行的總耗時(shí)
FGCT/FGC Full GC平均耗時(shí)
  • 查看一下GC執(zhí)行的頻率和詳細(xì)情況
    在命令行中加入-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:filename
    查看GC日志中每次GC的間隔時(shí)間,即可得出GC執(zhí)行的頻率
    也可以使用GcViewer工具,導(dǎo)入GC日志,進(jìn)行更詳細(xì)的分析(趨勢(shì)分析,什么時(shí)間段GC執(zhí)行得更頻繁,耗時(shí)更多等)

分析監(jiān)控結(jié)果

分析GC結(jié)果,確定是否需要調(diào)優(yōu),可參考以下標(biāo)準(zhǔn)(實(shí)際標(biāo)準(zhǔn)以應(yīng)用的實(shí)際情況為準(zhǔn))

  • Minor GC平均耗時(shí)少于50毫秒
  • Minor GC平均頻率少于10秒
  • Full GC平均耗時(shí)少于1秒
  • Full GC平均頻率少于10分鐘

當(dāng)出現(xiàn)OutOfMemoryError時(shí),要確定是什么問(wèn)題,是內(nèi)存分配不足還是因?yàn)閮?nèi)存泄漏或者沒(méi)有及時(shí),可以通過(guò)jmap命令或者在命令行加入-XX:+HeapDumpOnOutOfMemoryError,然后對(duì)dump出的Heap進(jìn)行分析(可以使用MAT或者jvisualvm工具)

調(diào)優(yōu)GC

基本策略

  1. 調(diào)整Heap中各區(qū)的大小,目標(biāo)是尋找一個(gè)平衡點(diǎn),在不發(fā)生OutOfMemoryError的情況下,滿足應(yīng)用響應(yīng)時(shí)間和吞吐量的需求
    增大內(nèi)存,可以減少GC執(zhí)行頻率,但會(huì)增加GC執(zhí)行時(shí)間
    減少內(nèi)存,可以減少GC執(zhí)行時(shí)間,但會(huì)增加GC執(zhí)行頻率

  2. 內(nèi)存不作動(dòng)態(tài)調(diào)整,因?yàn)槊看握{(diào)整內(nèi)存(Heap或Perm)都會(huì)觸發(fā)FullGC
    -Xms和-Xmx設(shè)置成相同(整個(gè)Heap大小不變)
    設(shè)置-Xmn(Young區(qū)大小不變,從而Old區(qū)的大小也不變)
    設(shè)置-XX:SurvivorRatio(Eden、兩個(gè)Survivor大小不變)
    -XX:PermSize和-XX:MaxPermSize設(shè)置成相同(Perm區(qū)大小不變)

  3. 避免主動(dòng)觸發(fā)GC
    程序調(diào)用了System.gc方法,會(huì)觸發(fā)FullGC
    在命令行中加入-XX:+DisableExplicitGC,可以忽略主動(dòng)GC的調(diào)用

響應(yīng)時(shí)間調(diào)優(yōu)

  1. 使用-XX:+UseParallelOldGC策略

  2. 觀察Minor GC的頻率和耗時(shí),確定Young大小
    確保只調(diào)整Young大小,不調(diào)整Old和Perm的大小
    耗時(shí)大,則減少Eden,頻率高則增加Eden,此時(shí)Survivor大小不變
    如果耗時(shí)和頻率都合適,則保持Eden大小不變,調(diào)整Survivor大小,相應(yīng)要調(diào)整Young大小,主要目的是減少?gòu)腨oung移到Old的對(duì)象數(shù)量
    觀察每次GC后是否有對(duì)象遷移到Old,如果有,則增加Survivor大小或?qū)ο驛ge大小,確保將對(duì)象盡可能地留在Young(設(shè)置-XX:+PrintTenuringDistribution,可以看到每次GC后Survivor的大小和各個(gè)Age對(duì)象的數(shù)量,如果Survivor滿了,則增加Survivor大小,如果Survivor未滿,但仍有對(duì)象遷移到Old(排除大對(duì)象),則設(shè)置age=max(age)+1,-XX:MaxTenuringThreshold=N[0-31])

  3. 觀察Full GC的頻率和耗時(shí),確定Old大小
    確保只調(diào)整Old大小,不調(diào)整Young和Perm大小
    耗時(shí)大則減少Old,頻率高則增加Old
    如果調(diào)整后仍然不能滿足耗時(shí)需求,則考慮使用CMS策略。此時(shí)Old要增大20%-30%,因?yàn)镃MS會(huì)產(chǎn)生碎片,要預(yù)留更多的內(nèi)存給應(yīng)用,否則容易產(chǎn)生concurrent mode error錯(cuò)誤,會(huì)退化成Serial回收,耗時(shí)更大。如果出現(xiàn)concurrent mode error,可以增大Old或者減少碎片整理的百分比(-XX:CMSInitiatingOccupancyFraction=N),增大CMS的頻率,加快收集Old

吞吐量調(diào)優(yōu)

在滿足響應(yīng)時(shí)間的前提下,增加Young和Old的大小,然后再進(jìn)行響應(yīng)時(shí)間的分析

推薦配置

基本配置

-Xms=-Xmx
-XX:PermSize=-XX:MaxPermSize
設(shè)置-Xmn
設(shè)置-XX:SurvivorRatio
-Xss=256k(默認(rèn)是1M,一般不需要那么大,如果發(fā)生StackOverflowError,則增加此值)
-XX:-UseAdaptiveSizePolicy(不允許JVM動(dòng)態(tài)調(diào)整各區(qū)的大?。?br> -XX:+DisableExplicitGC(關(guān)閉主動(dòng)GC調(diào)用)
-XX:+HeapDumpOnOutOfMemoryError
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintHeapAtGC
-Xloggc:filename

CMS配置

-XX:+UseConcMarkSweepGC
-XX:+CMSParallelRemarkEnabled
-XX:+CMSScavengeBeforeRemark
-XX:+ ScavengeBeforeFullGC
-XX+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction=X
-XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSInitiatingOccupancyFraction=70
-XX:CMSInitiatingPermOccupancyFraction=80
-XX:+CMSClassUnloadingEnabled
-XX:+CMSPermGenSweepingEnabled

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容