JVM調優引數簡介、調優目標及調優經驗
一、JVM調優引數簡介
1、 JVM引數簡介
-XX 引數被稱為不穩定引數,之所以這麼叫是因為此類引數的設定很容易引起JVM 效能上的差異,使JVM 存在極大的不穩定性。如果此類引數設定合理將大大提高JVM 的效能及穩定性。
不穩定引數語法規則:
1.布林型別引數值-XX:+<option> '+'表示啟用該選項
-XX:-<option> '-'表示關閉該選項
2.數字型別引數值:
-XX:<option>=<number> 給選項設定一個數字型別值,可跟隨單位,例如:'m'或'M'表示兆位元組;'k'或'K'千位元組;'g'或'G'千兆位元組。32K與32768是相同大小的。
3.字串型別引數值:
-XX:<option>=<string> 給選項設定一個字串型別值,通常用於指定一個檔案、路徑或一系列命令列表。
例如:-XX:HeapDumpPath=./dump.core
2、 JVM引數示例
配置: -Xmx4g –Xms4g –Xmn1200m –Xss512k -XX:NewRatio=4 -XX:SurvivorRatio=8 -XX:PermSize=100m
-XX:MaxPermSize=256m -XX:MaxTenuringThreshold=15
解析:-Xmx4g:堆記憶體最大值為4GB。
-Xms4g:初始化堆記憶體大小為4GB 。
-Xmn1200m:設定年輕代大小為1200MB。增大年輕代後,將會減小年老代大小。此值對系統性能影響較大,Sun官方推薦配置為整個堆的3/8。
-Xss512k:設定每個執行緒的堆疊大小。JDK5.0以後每個執行緒堆疊大小為1MB,以前每個執行緒堆疊大小為256K。應根據應用執行緒所需記憶體大小進行調整。在相同實體記憶體下,減小這個值能生成更多的執行緒。但是作業系統對一個程序內的執行緒數還是有限制的,不能無限生成,經驗值在3000~5000左右。
-XX:NewRatio=4:設定年輕代(包括Eden和兩個Survivor區)與年老代的比值(除去持久代)。設定為4,則年輕代與年老代所佔比值為1:4,年輕代佔整個堆疊的1/5
-XX:SurvivorRatio=8:設定年輕代中Eden區與Survivor區的大小比值。設定為8,則兩個Survivor區與一個Eden區的比值為2:8,一個Survivor區佔整個年輕代的1/10
-XX:PermSize=100m:初始化永久代大小為100MB。
-XX:MaxPermSize=256m:設定持久代大小為256MB。
-XX:MaxTenuringThreshold=15:設定垃圾最大年齡。如果設定為0的話,則年輕代物件不經過Survivor區,直接進入年老代。對於年老代比較多的應用,可以提高效率。如果將此值設定為一個較大值,則年輕代物件會在Survivor區進行多次複製,這樣可以增加物件再年輕代的存活時間,增加在年輕代即被回收的概論。
二、JVM調優目標
1. 何時需要做jvm調優?1. heap 記憶體(老年代)持續上漲達到設定的最大記憶體值;
2. Full GC 次數頻繁;
3. GC 停頓時間過長(超過1秒);
4. 應用出現OutOfMemory 等記憶體異常;
5. 應用中有使用本地快取且佔用大量記憶體空間;
6. 系統吞吐量與響應效能不高或下降。
2. JVM調優原則
1.多數的Java應用不需要在伺服器上進行JVM優化;
2.多數導致GC問題的Java應用,都不是因為我們引數設定錯誤,而是程式碼問題;
3.在應用上線之前,先考慮將機器的JVM引數設定到最優(最適合);
4.減少建立物件的數量;
5.減少使用全域性變數和大物件;
6.JVM優化是到最後不得已才採用的手段;
7.在實際使用中,分析GC情況優化程式碼比優化JVM引數更好;
3. JVM調優目標
1. GC低停頓;
2. GC低頻率;
3. 低記憶體佔用;
4. 高吞吐量;
JVM調優量化目標(示例):
1. Heap 記憶體使用率 <= 70%;
2. Old generation記憶體使用率<= 70%;
3. avgpause <= 1秒;
4. Full gc 次數0 或 avg pause interval >= 24小時 ;
注意:不同應用,其JVM調優量化目標是不一樣的。
三、JVM調優經驗
1. JVM調優經驗總結
JVM調優的一般步驟為:
第1步:分析GC日誌及dump檔案,判斷是否需要優化,確定瓶頸問題點;
第2步:確定JVM調優量化目標;
第3步:確定JVM調優引數(根據歷史JVM引數來調整);
第4步:調優一臺伺服器,對比觀察調優前後的差異;
第5步:不斷的分析和調整,直到找到合適的JVM引數配置;
第6步:找到最合適的引數,將這些引數應用到所有伺服器,並進行後續跟蹤。
2. JVM調優重要引數解析
注意:不同應用,其JVM最佳穩定引數配置是不一樣的。
配置: -server
-Xms12g -Xmx12g -XX:PermSize=500m -XX:MaxPermSize=1000m -Xmn2400m -XX:SurvivorRatio=1 -Xss512k -XX:MaxDirectMemorySize=1G
-XX:+DisableExplicitGC -XX:CompileThreshold=8000 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC
-XX:+UseCompressedOops -XX:CMSInitiatingOccupancyFraction=60 -XX:ConcGCThreads=4
-XX:MaxTenuringThreshold=10 -XX:ParallelGCThreads=8
-XX:+ParallelRefProcEnabled -XX:+CMSClassUnloadingEnabled -XX:+CMSParallelRemarkEnabled
-XX:CMSMaxAbortablePrecleanTime=500 -XX:CMSFullGCsBeforeCompaction=4
XX:+UseCMSInitiatingOccupancyOnly -XX:+UseCMSCompactAtFullCollection
-XX:+HeapDumpOnOutOfMemoryError -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/weblogic/gc/gc_$$.log
重要引數(可調優)解析:
-Xms12g:初始化堆記憶體大小為12GB。
-Xmx12g:堆記憶體最大值為12GB 。
-Xmn2400m:新生代大小為2400MB,包括 Eden區與2個Survivor區。
-XX:SurvivorRatio=1:Eden區與一個Survivor區比值為1:1。
-XX:MaxDirectMemorySize=1G:直接記憶體。報java.lang.OutOfMemoryError: Direct buffer memory 異常可以上調這個值。
-XX:+DisableExplicitGC:禁止執行期顯式地呼叫 System.gc() 來觸發fulll GC。
注意: Java RMI的定時GC觸發機制可通過配置-Dsun.rmi.dgc.server.gcInterval=86400來控制觸發的時間。
-XX:CMSInitiatingOccupancyFraction=60:老年代記憶體回收閾值,預設值為68。
-XX:ConcGCThreads=4:CMS垃圾回收器並行執行緒線,推薦值為CPU核心數。
-XX:ParallelGCThreads=8:新生代並行收集器的執行緒數。
-XX:MaxTenuringThreshold=10:設定垃圾最大年齡。如果設定為0的話,則年輕代物件不經過Survivor區,直接進入年老代。對於年老代比較多的應用,可以提高效率。如果將此值設定為一個較大值,則年輕代物件會在Survivor區進行多次複製,這樣可以增加物件再年輕代的存活時間,增加在年輕代即被回收的概論。
-XX:CMSFullGCsBeforeCompaction=4:指定進行多少次fullGC之後,進行tenured區 記憶體空間壓縮。
-XX:CMSMaxAbortablePrecleanTime=500:當abortable-preclean預清理階段執行達到這個時間時就會結束。
3. 觸發Full GC的場景及應對策略
年輕代空間(包括 Eden 和 Survivor 區域)回收記憶體被稱為 Minor GC,對老年代GC稱為MajorGC,而Full GC是對整個堆來說的,在最近幾個版本的JDK裡預設包括了對永生帶即方法區的回收(JDK8中無永生帶了),出現Full GC的時候經常伴隨至少一次的Minor GC,但非絕對的。MajorGC的速度一般會比Minor GC慢10倍以上。
觸發Full GC的場景及應對策略:
1.System.gc()方法的呼叫,應對策略:通過-XX:+DisableExplicitGC來禁止呼叫System.gc ;
2.老年代代空間不足,應對策略:讓物件在Minor GC階段被回收,讓物件在新生代多存活一段時間,不要建立過大的物件及陣列;
3.永生區空間不足,應對策略:增大PermGen空間
4.GC時出現promotionfailed和concurrent mode failure,應對策略:增大survivor space
5.Minor GC後晉升到舊生代的物件大小大於老年代的剩餘空間,應對策略:增大Tenured space 或下調CMSInitiatingOccupancyFraction=60
6. 記憶體持續增漲達到上限導致Full GC ,應對策略:通過dumpheap 分析是否存在記憶體洩漏
4. Gc日誌分析工具
藉助GCViewer日誌分析工具,可以非常直觀地分析出待調優點。
可從以下幾方面來分析:
1.Memory,分析Totalheap、Tenuredheap、Youngheap記憶體佔用率及其他指標,理論上記憶體佔用率越小越好;
2.Pause ,分析Gc pause、Fullgc pause、Total pause三個大項中各指標,理論上GC次數越少越好,GC時長越小越好;
5. MAT 堆記憶體分析工具
EclipseMemory Analysis Tools (MAT) 是一個分析Java堆資料的專業工具,用它可以定位記憶體洩漏的原因。
參考自以下連結內容:
https://blog.csdn.net/u011683530/article/details/51013219
https://www.cnblogs.com/God-froest/p/jvm_1_3.html