目標(biāo)
滿足應(yīng)用的響應(yīng)時(shí)間和吞吐量需求够掠,盡量減少GC對(duì)應(yīng)用的影響
原則
- 大部分時(shí)候都不需要調(diào)優(yōu)GC,只需配置-Xms贾陷,-Xmx即可逮京,JVM會(huì)自動(dòng)進(jìn)行調(diào)整
- 先滿足響應(yīng)時(shí)間需求卿堂,再滿足吞吐量需求
- FullGC對(duì)應(yīng)用的影響更大,要盡量減少FullGC執(zhí)行的時(shí)間和頻率懒棉,減少轉(zhuǎn)移到Old的對(duì)象數(shù)量
監(jiān)控GC狀態(tài)
- 查看一下GC的總體執(zhí)行情況
jstat -gcutil pid
參數(shù) | 說明 |
---|---|
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í),要確定是什么問題倔韭,是內(nèi)存分配不足還是因?yàn)閮?nèi)存泄漏或者沒有及時(shí)术浪,可以通過jmap命令或者在命令行加入-XX:+HeapDumpOnOutOfMemoryError,然后對(duì)dump出的Heap進(jìn)行分析(可以使用MAT或者jvisualvm工具)
調(diào)優(yōu)GC
基本策略
調(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í)行頻率內(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ū)大小不變)避免主動(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)
使用-XX:+UseParallelOldGC策略
觀察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])觀察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ū)的大小)
-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