生產環境下JVM調優參數的設置實例


 正文前先來一波福利推薦:

 福利一:

百萬年薪架構師視頻,該視頻可以學到很多東西,是本人花錢買的VIP課程,學習消化了一年,為了支持一下女朋友公眾號也方便大家學習,共享給大家。

福利二:

畢業答辯以及工作上各種答辯,平時積累了不少精品PPT,現在共享給大家,大大小小加起來有幾千套,總有適合你的一款,很多是網上是下載不到。

獲取方式:

微信關注 精品3分鍾 ,id為 jingpin3mins,關注后回復   百萬年薪架構師 ,精品收藏PPT  獲取雲盤鏈接,謝謝大家支持!

-----------------------正文開始---------------------------

 

JVM基礎:生產環境參數實例及分析

 

原始配置:

-Xms128m  
-Xmx128m  
-XX:NewSize=64m  
-XX:PermSize=64m  
-XX:+UseConcMarkSweepGC  
-XX:CMSInitiatingOccupancyFraction=78 
-XX:ThreadStackSize=128k
-Xloggc:logs/gc.log -Dsun.rmi.dgc.server.gcInterval=3600000 -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.server.exceptionTrace=true

 

問題:

◆  permsize 設置較小,很容易達到報警范圍(0.8)

◆ 沒有設置MaxPermSize,堆增長會帶來額外壓力。

◆ NewSize較大,old gen 剩余空間64m,一方面可能會帶來old區容易增長到報警范圍(監控數據顯示oldgenused長期在50m左右,接近78%,容易出現full gc),另一方面也存在promontion fail風險。

Jvm內存調優:

-Xms128m  
-Xmx128m  
-Xmn24m  
-XX:PermSize=80m  
-XX:MaxPermSize=80m  
-Xss256k-XX:SurvivorRatio=1 
-XX:MaxTenuringThreshold=20 
-XX:+UseParNewGC  
-XX:+UseConcMarkSweepGC  
-XX:CMSInitiatingOccupancyFraction=75 
-XX:+UseCMSCompactAtFullCollection  
-XX:+CMSParallelRemarkEnabled  
-XX:CMSFullGCsBeforeCompaction=2 
-XX:SoftRefLRUPolicyMSPerMB=0 
-XX:+PrintClassHistogram  
-XX:+PrintGCDetails  
-XX:+PrintGCTimeStamps  
-XX:+PrintHeapAtGC  
-Xloggc:logs/gc.log  
-Dsun.rmi.dgc.server.gcInterval=3600000 
-Dsun.rmi.dgc.client.gcInterval=3600000 
-Dsun.rmi.server.exceptionTrace=true 

 

修改點:

◆ PermSize與MaxPermSize都設置為80,一方面避免non heap warn(報警閥值0.8 非對內存一般占用到60M以內),一方面避免堆伸縮帶來的壓力

◆ 通過設置Xmn=24M及SurvivorRatio=1 使得Eden區=from space=to space=8M,降低了Eden區大小,降低YGC的時間(降低到3-4ms左右),同時通過設MaxTenuringThreshold=20,使得old gen的增長很緩慢。帶來的問題是YGC的次數明顯提高了很多。

◆ 其他參數優化 修改后帶來的好處見另一篇文章對參數的詳細介紹

 

再次進行內存調優:

-Xms128m  
-Xmx128m  
-Xmn36m  
-XX:PermSize=80m  
-XX:MaxPermSize=80m  
-Xss256k  
-XX:SurvivorRatio=1 
-XX:MaxTenuringThreshold=20 
-XX:+UseParNewGC  
-XX:+UseConcMarkSweepGC  
-XX:CMSInitiatingOccupancyFraction=73 
-XX:+UseCMSCompactAtFullCollection  
-XX:+CMSParallelRemarkEnabled  
-XX:CMSFullGCsBeforeCompaction=2 
-XX:SoftRefLRUPolicyMSPerMB=0 
-XX:+PrintClassHistogram  
-XX:+PrintGCDetails  
-XX:+PrintGCTimeStamps  
-XX:+PrintHeapAtGC  
-Xloggc:logs/gc.log  
-Dsun.rmi.dgc.server.gcInterval=3600000 
-Dsun.rmi.dgc.client.gcInterval=3600000 
-Dsun.rmi.server.exceptionTrace=true 

 

修改點:

在上面的基礎上調整Xmn大小到36M,設置CMSInitiatingOccupancyFraction=73。

Dden區與Survivor區大小都增加到12M,通過CMSInitiatingOccupancyFraction計算公式,計算得出value為73是,可以避免promotion faild問題,因為 年老去的大小為 (128m - 36m)0*(1-0.73) = 24.86m  完全可以放一下一個Eden區的大小;

同時滿足堆內存監控報警值在80%:內存大小128M*80%=102.4M, 102.4M-36M=66.4M (老生代達到此值也會報警 老生代達到92M*0.73 =67.15M)將發生Full GC,所以在老生代大小達到66.4M時也就是WARN報警時將很有可能出現Full GC。

增大了Eden和Survivor區的值,會減小YGC的次數,但由於空間變大理論上也會相應的增加YGC的時間,不過由於新生代本身就很小(才36M)這點兒變化可以忽略掉。實際的監控值顯示YGC的時間在4-5ms之間。是可以接受范圍。

SurvivorRatio 這個值還得在仔細考慮下,有待優化中。

 

網上某個牛人的配置 :每天幾百萬pv一點問題都沒有,網站沒有停頓

$JAVA_ARGS  
.="  
-Dresin.home=$SERVER_ROOT  
-server  
-Xms6000M  
-Xmx6000M  
-Xmn500M  
-XX:PermSize=500M  
-XX:MaxPermSize=500M  
-XX:SurvivorRatio=65536 
-XX:MaxTenuringThreshold=0 
-Xnoclassgc  
-XX:+DisableExplicitGC  
-XX:+UseParNewGC  
-XX:+UseConcMarkSweepGC  
-XX:+UseCMSCompactAtFullCollection  
-XX:CMSFullGCsBeforeCompaction=0 
-XX:+CMSClassUnloadingEnabled-XX:  
-CMSParallelRemarkEnabled  
-XX:CMSInitiatingOccupancyFraction=90 
-XX:SoftRefLRUPolicyMSPerMB=0 
-XX:+PrintClassHistogram  
-XX:+PrintGCDetails  
-XX:+PrintGCTimeStamps  
-XX:+PrintHeapAtGC  
-Xloggc:log/gc.log  
"; 

 

該調優設置中:

-XX:SurvivorRatio=65536  -XX:MaxTenuringThreshold=0  目的就是去掉了救助空間 也就是年輕代中只有Eden區 Eden的對象 會直接到年老區中;

-Xnoclassgc 禁用類垃圾回收,性能會高一點;

-XX:+DisableExplicitGC禁止System.gc(),免得程序員誤調用gc方法影響性能;

-XX:+UseParNewGC,對年輕代采用多線程並行回收,這樣收得快;

帶CMS(並發收集算法)參數的都是和並發回收相關的,不明白的可以上網搜索;

CMSInitiatingOccupancyFraction,這個參數設置有很大技巧,基本上滿足如下公式:

 

(Xmx-Xmn)*(100-CMSInitiatingOccupancyFraction)/100>=Xmn

 

就不會出現promotion failed;

在我的應用中Xmx是6000,Xmn是500,那么Xmx-Xmn是5500兆,也就是年老代有5500兆,CMSInitiatingOccupancyFraction=90說明年老代到90%滿的時候開始執行對年老代的並發垃圾回收(CMS),這時還剩10%的空間是5500*10%=550兆,所以即使Xmn(也就是年輕代共500兆)里所有對象都搬到年老代里,550兆的空間也足夠了,所以只要滿足上面的公式,就不會出現垃圾回收時的promotion failed;

SoftRefLRUPolicyMSPerMB這個參數我認為可能有點用,官方解釋是softly reachable objects will remain alive for some amount of time after the last time they were referenced. The default value is one second of lifetime per free megabyte in the heap,我覺得沒必要等1秒;

 

繼續進行jvm調優:

-Xmx4000M  
-Xms4000M  
-Xmn600M  
-XX:PermSize=500M  
-XX:MaxPermSize=500M  
-Xss256K  
-XX:+DisableExplicitGC  
-XX:SurvivorRatio=1 
-XX:+UseConcMarkSweepGC  
-XX:+UseParNewGC  
-XX:+CMSParallelRemarkEnabled  
-XX:+UseCMSCompactAtFullCollection  
-XX:CMSFullGCsBeforeCompaction=0 
-XX:+CMSClassUnloadingEnabled  
-XX:LargePageSizeInBytes=128M  
-XX:+UseFastAccessorMethods  
-XX:+UseCMSInitiatingOccupancyOnly  
-XX:CMSInitiatingOccupancyFraction=80 
-XX:SoftRefLRUPolicyMSPerMB=0 
-XX:+PrintClassHistogram  
-XX:+PrintGCDetails  
-XX:+PrintGCTimeStamps  
-XX:+PrintHeapAtGC  
-Xloggc:log/gc.log 

 

改進說明:

第一次的調優方法不太好,因為沒有用到救助空間,所以年老代容易滿,CMS執行會比較頻繁(年老代進行一次GC 則年輕代也要及進行一次GC 想當於一次Full GC)。我改善了一下,還是用救助空間,但是把救助空間加大,這樣也不會有promotion failed。
具體操作上,32位Linux和64位Linux好像不一樣,64位系統似乎只要配置MaxTenuringThreshold參數,CMS還是有暫停。為了解決暫停問題和promotion failed問題,最后我設置-XX:SurvivorRatio=1 ,並把MaxTenuringThreshold去掉,這樣即沒有暫停又不會有promotoin failed,而且更重要的是,年老代和永久代上升非常慢(因為好多對象到不了年老代就被回收了),所以CMS執行頻率非常低,好幾個小時才執行一次,這樣,服務器都不用重啟了。

某網友的調優方案:

$JAVA_ARGS  
.="  
-Dresin.home=$SERVER_ROOT  
-server  
-Xmx3000M  
-Xms3000M  
-Xmn600M  
-XX:PermSize=500M  
-XX:MaxPermSize=500M  
-Xss256K  
-XX:+DisableExplicitGC  
-XX:SurvivorRatio=1 
-XX:+UseConcMarkSweepGC  
-XX:+UseParNewGC  
-XX:+CMSParallelRemarkEnabled  
-XX:+UseCMSCompactAtFullCollection  
-XX:CMSFullGCsBeforeCompaction=0 
-XX:+CMSClassUnloadingEnabled  
-XX:LargePageSizeInBytes=128M  
-XX:+UseFastAccessorMethods  
-XX:+UseCMSInitiatingOccupancyOnly  
-XX:CMSInitiatingOccupancyFraction=70 
-XX:SoftRefLRUPolicyMSPerMB=0 
-XX:+PrintClassHistogram  
-XX:+PrintGCDetails  
-XX:+PrintGCTimeStamps  
-XX:+PrintHeapAtGC  
-Xloggc:log/gc.log"; 

 

64位jdk參考設置,年老代漲得很慢,CMS執行頻率變小,CMS沒有停滯,也不會有promotion failed問題,內存回收得很干凈。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM