JVM參數之GC配置


 本文轉載:milkty的jvm參數

  在學習java的jvm內存板塊時,最后總會涉及到一些JVM參數。年輕代、老年代、永久代等各項都可以通過JVM參數來設置大小。在實際設置啟動參數時,一般只會設置幾個,實際參數有上百個,很多都有默認值。

  JVM中,上一個版本的默認值並不一定是下一版本的默認值,不同的GC方式有不同的整套默認值,os不同,jvm位數不同,默認值都會有所區別。jdk1.6 高版本的update中參數得有600個。參數過多,不需要全部了解,只要知道的是找到默認值的方法,掌握默認值的大概量級、在不同的版本下哪些是常用的默認參數,哪些是必須設置的參數,哪些是可以選擇的,哪些是盡量不要碰的。

 

看默認值的方法?

1、通過jinfo來獲取。比如,jinfo -flag -PrintHeapAtGC=true <pid>

2、通過java -XX:+PrintFlagsFinal -version來獲取結果。

3、通過java -XX:+PrintCommandLineFlags來打印真正的參數啟動命令。

4、如果這些參數還不夠全,可以打開幾個開關:

java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal -version

大部分的參數都可以安全的看到默認值,但是某些參數需要在生產環境運行時來調整。(后面花括號里面有product的表示可以在啟動參數中設置的,花括號里面是“product rw”的表示還可以在jvm啟動后使用類似下面的命令來設置這些參數)項多時,可以根據grep命令指定單一項參數。

 

復制代碼
$ java -XX:+PrintCommandLineFlags -version
-XX:InitialHeapSize=128163136 -XX:MaxHeapSize=2050610176 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC 
java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)
復制代碼

 

 JVM參數設置中,有的是同一類型有很多參數,而且都有默認值。如-XX:NewSize、-XX:MaxNewSize,設置了xmn后相當於將這兩值值設置為一樣大。也有用參數-XX:NewRatio來設置的。不要混用,否則實際就並不知如何執行的。

 

參數 -XX:+PrintTenuringDistribution 輸出中的部分值可以通過其它參數控制。

通過 -XX:InitialTenuringThreshold 和 -XX:MaxTenuringThreshold 可以設定老年代閥值的初始值和最大值。

通過參數 -XX:TargetSurvivorRatio 設定幸存區的目標使用率.例如 , -XX:MaxTenuringThreshold=10 -XX:TargetSurvivorRatio=90 設定老年代閥值的上限為10,幸存區空間目標使用率為90%。

 

新生代的GC 使用復制算法。

進入老年代的可能:1)復制對象超過gc次數;2)復制對象大於from/to區大小;3)創建對象大於新生代剩余空間大小;
如果新生代過小,會導致新生對象很快就晉升到老年代中,在老年代中對象很難被回收。

有多種方式,設置新生代行為,沒有通用准則。我們必須清楚以下2中情況:
1 如果從年齡分布中發現,有很多對象的年齡持續增長,在到達老年代閥值之前。這表示 -XX:MaxTenuringThreshold 設置過大
2 如果 -XX:MaxTenuringThreshold 的值大於1,但是很多對象年齡從未大於1.應該看下幸存區的目標使用率。如果幸存區使用率從未到達,這表示對象都被GC回收,這正是我們想要的。 如果幸存區使用率經常達到,有些年齡超過1的對象被移動到老年代中。這種情況,可以嘗試調整幸存區大小或目標使用率。

 

jvm參數設置輸出結果
1、gc日志輸出
在 jvm啟動參數中加入 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimestamps -XX:+PrintGCApplicationStopedTime ,
其他還有 -Xloggc:文件路徑, -verbose:gc -XX:+PrintTenuringDistribution
 
-XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime
打開這些選項能夠記錄下所有的安全點(應用程序線程可以被安全地停止掉的那個時間點),而不止是GC暫停的。
Application time: 0.3440086 seconds
Total time for which application threads were stopped: 0.0620105 seconds
Application time: 0.2100691 seconds
Total time for which application threads were stopped: 0.0890223 seconds

從中可以得知應用程序在前344毫秒中是在處理實際工作的,然后將所有線程暫停了62毫秒,緊接着又工作了210ms,然后又暫停了89ms。

-XX:+PrintGCDetails -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime輸出則變成這樣了;

[Full GC (Ergonomics) [PSYoungGen: 1375253K->0K(1387008K)] [ParOldGen: 2796146K->2049K(1784832K)] 4171400K->2049K(3171840K), [Metaspace: 3134K->3134K(1056768K)], 0.0571841 secs] [Times: user=0.02 sys=0.04, real=0.06 secs]
Total time for which application threads were stopped: 0.0572646 seconds, Stopping threads took: 0.0000088 seconds

綜上可知,應用線程被強制暫停了57ms來進行垃圾回收。其中又有0.008ms是用來等待所有的應用線程都到達安全點。

詳細了解安全點信息:-XX:+PrintSafepointStatistics -XX:PrintSafepointStatisticsCount=1 會使得JVM會將一些額外的信息記錄到標准輸出中

參數 -XX:+PrintTenuringDistribution 指定JVM 在每次新生代GC時,輸出幸存區中對象的年齡分布。

 
2、jvm outOfMemory時dump內存
-XX:+HeapDumpOnOutOfMemoryError
 
3、jvm FGC前后dump內存
XX:+HeapDumpBeforeFullGC -XX:+HeapDumpAfterFullGC
 
4 crash日志
  [GC [DefNew: 1986K->128K(2112K),0.0011191 secs] 27809K->27808K(30528K), 0.0011425 secs] [Times: user=0.00sys=0.01, real=0.00 secs]

[GC [ParNew: 1990K->132K(2112K),0.0007742 secs] 24112K->24110K(30528K), 0.0007964 secs] [Times: user=0.00sys=0.00, real=0.00 secs]

[GC [PSYoungGen:7449K->3728K(7552K)] 66980K->66980K(75136K), 0.0022792 secs] [Times:user=0.00 sys=0.00, real=0.00 secs]

GC[ParNew 表示使用的是parNew收集器。

GC[DefNew 表示用的是serial收集器。

[GC[PSYoungGen 表示用的是Parallel Scavenge收集器。


免責聲明!

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



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