本文轉載: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的對象被移動到老年代中。這種情況,可以嘗試調整幸存區大小或目標使用率。
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時,輸出幸存區中對象的年齡分布。
[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收集器。