#今天來熟悉一下,關於JVM
調優常用的一些參數。
X或XX開頭的都是非標準化參數
意思就是說標準化參數不會改變,非標準化參數可能在每個JDK
版本中有所變化,但是就目前來看X開頭的非標準化的參數改變的也是非常少。
格式:-XX:[+-]<name> 表示启用或者禁用name属性。 例子:-XX:+UseG1GC(表示启用G1垃圾收集器)
-XX: PrintCommandLineFlags
查看目前JVM
設定過的相關參數:
#根據JVM
參數開頭可以區分參數類型,共三類別:“-
”、“-X
”、“-XX
”,
標準參數(-):所有的JVM實作都必須實作這些參數的功能,而且向後相容;
範例:-verbose:class
,-verbose:gc
,-verbose:jni… …
非標準參數(-X):預設jvm實作這些參數的功能,但並不保證所有jvm實作都滿足,且不保證向後相容;
例子:Xms20m
,-Xmx20m
,-Xmn20m
,-Xss128k…
#非Stable參數(-XX) :此類參數各個jvm實作會有所不同,將來可能隨時取消,需要慎重使用;
範例:-XX: PrintGCDetails
,-XX:-UseParallelGC
,-XX: PrintGCTimeStamps…
-Xms
初始堆大小,ms是memory start的簡稱,等價於-XX:InitialHeapSize
-Xmx
最大堆大小,mx是memory max的簡稱,等價於參數-XX:MaxHeapSize
注意:在通常情況下,伺服器項目在運作過程中,堆空間會持續的收縮與擴張,勢必會造成不必要的系統壓力。
所以在生產環境中,
JVM
的Xms
和Xmx
要設定成大小一樣的,能夠避免GC
在調整堆大小帶來的不必要的壓力。
-XX:NewSize=n
設定年輕代大小-XX:NewRatio=n
設定年輕代和年老代的比值。
如:-XX:NewRatio=3
,表示年輕代與年老代比值為1:3
,年輕代佔整個年輕代年老代和的1/4,預設新生代和老年代的比例=1:2
。 -XX:SurvivorRatio=n
年輕代中Eden區與兩個Survivor區的比值。
注意Survivor區有兩個,預設是8,表示:Eden:S0:S1=8:1:1
如:-XX: SurvivorRatio=3
,表示Eden:Survivor
=3:2,一個Survivor區佔整個年輕代的1/5。
-XX:MetaspaceSize:Metaspace
空間初始大小,如果不設定的話,預設是20.79M,這個初始大小是觸發首次Metaspace Full GC
的閾值。
例如:-XX:MetaspaceSize=256M
-XX:MaxMetaspaceSize:Metaspace
最大值,預設不限制大小,但是線上環境建議設定。
例如:-XX:MaxMetaspaceSize=256M
-XX:MinMetaspaceFreeRatio:最小空閒比,當Metaspace
發生GC 後,會計算Metaspace
的空閒比,如果空閒比(空閒空間/目前Metaspace
大小)小於此值,就會觸發Metaspace
擴充。預設值是40 ,也就是40%,例如-XX:MinMetaspaceFreeRatio=40
-XX:MaxMetaspaceFreeRatio:最大空閒比,當Metaspace
發生GC 後,會計算Metaspace
的空閒比,如果空閒比(空閒空間/目前Metaspace 大小)大於此值,就會觸發Metaspace
釋放空間。預設值是 70 ,也就是 70%,例如 -XX:MaxMetaspaceFreeRatio=70
建議將
MetaspaceSize
和MaxMetaspaceSize
設定為相同大小,避免頻繁擴容。
#-Xss:堆疊空間大小,堆疊是執行緒獨佔的,所以是一個執行緒使用堆疊空間的大小。
例如:-Xss256K
,如果不設定此參數,預設值是1M
,一般來講設定成 256K
就夠了。
Serial垃圾收集器(新世代)
開啟:-XX: UseSerialGC 關閉:-XX:-UseSerialGC //新生代使用Serial 老年代則使用SerialOld
ParNew垃圾收集器(新生代)
開啟 -XX: UseParNewGC 關閉 -XX:-UseParNewGC //新生代使用功能ParNew 老年代則使用功能CMS
Parallel Scavenge收集器(新生代)
開啟 -XX: UseParallelOldGC 關閉 -XX:-UseParallelOldGC //新生代使用功能Parallel Scavenge 老年代將會使用Parallel Old收集器
#ParallelOl垃圾收集器(舊年代)
開啟 -XX: UseParallelGC 關閉 -XX:-UseParallelGC //新生代使用功能Parallel Scavenge 老年代將會使用Parallel Old收集器
CMS垃圾收集器(老年代)
開 -XX: UseConcMarkSweepGC 關閉 -XX:-UseConcMarkSweepGC
G1垃圾收集器
開啟 -XX: UseG1GC 關閉-XX:-UseG1GC
#GC停頓時間,垃圾收集器會嘗試用各種手段達到這個時間,例如減小年輕代
-XX:MaxGCPauseMillis
堆佔用了多少比例的時候觸發GC,就即觸發標記週期的Java 堆佔用率閾值。預設佔用率是整個Java 堆的45%
-XX:InitiatingHeapOccupancyPercent=n
新生代可容納的最大物件,大於則直接會分配到老年代,0代表沒有限制。
-XX:PretenureSizeThreshold=1000000 //
進入老年代最小的GC年齡,年輕代物件轉換為老年代物件最小年齡值,預設值7
-XX:InitialTenuringThreshol=7
#升級老年代年齡,最大值15
-XX:MaxTenuringThreshold
GC並行執行執行緒數
##-XX: ParallelGCThreads=16停用System.gc(),由於方法預設會觸發FGC,並且忽略參數中的UseG1GC 和UseConcMarkSweepGC,因此必要時可以停用該方法。
-XX:- DisableExplicitGC設定吞吐量大小,預設99
XX:GCTimeRatio#開啟自適應策略,各區域的比率,晉升老年代的年齡等參數會被自動調整。以達到吞吐量,停頓時間的平衡點。
XX:UseAdaptiveSizePolicy設定GC時間佔用程式運行時間的百分比
GCTimeRatio
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath
堆内存出现OOM
的概率是所有内存耗尽异常中最高的,出错时的堆内信息对解决问题非常有帮助。
所以给JVM
设置这个参数(-XX:+HeapDumpOnOutOfMemoryError
),让JVM
遇到OOM
异常时能输出堆内信息,并通过(-XX:+HeapDumpPath
)参数设置堆内存溢出快照输出的文件地址。
这对于特别是对相隔数月才出现的OOM
异常尤为重要。
-Xms10M -Xmx10M -Xmn2M -XX:SurvivorRatio=8 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\study\log_hprof\gc.hprof
-XX:OnOutOfMemoryError
表示发生OOM后
,运行jconsole.exe
程序。
这里可以不用加“”,因为jconsole.exe
路径Program Files含有空格。利用这个参数,我们可以在系统OOM
后,自定义一个脚本,可以用来发送邮件告警信息,可以用来重启系统等等。
-XX:OnOutOfMemoryError="C:\Program Files\Java\jdk1.8.0_151\bin\jconsole.exe"
java -Xmx3550m -Xms3550m -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxPermSize=16m -XX:MaxTenuringThreshold=0
-Xmx3500m
设置JVM
最大可用内存为3550M。
-Xms3500m
设置JVM
初始
内存为3550m
。此值可以设置与-Xmx
相同,以避免每次垃圾回收完成后JVM重新分配内存。-Xmn2g
设置年轻代大小为2G
。
整个堆大小=年轻代大小 + 年老代大小 + 方法区大小
-Xss128k
设置每个线程的堆栈大小。
JDK1.5
以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。
-XX:NewRatio=4
设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5 。
-XX:SurvivorRatio=4
设置年轻代中Eden区与Survivor区的大小比值。
设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6 -XX:MaxPermSize=16m
设置持久代大小为16m。
-XX:MaxTenuringThreshold=0
设置垃圾最大年龄。
如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象在年轻代的存活时间,增加在年轻代即被回收的概论。
比如,我们启动一个user-service项目:
java -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UseGCLogFileRotation -XX:+PrintHeapAtGC -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=20M -Xloggc:/opt/user-service-gc-%t.log -jar user-service-1.0-SNAPSHOT.jar
参数解释:
-Xloggc:/opt/app/ard-user/user-service-gc-%t.log 设置日志目录和日志名称 -XX:+UseGCLogFileRotation 开启滚动生成日志 -XX:NumberOfGCLogFiles=5 滚动GC日志文件数,默认0,不滚动 -XX:GCLogFileSize=20M GC文件滚动大小,需开启UseGCLogFileRotation -XX:+PrintGCDetails 开启记录GC日志详细信息(包括GC类型、各个操作使用的时间),并且在程序运行结束打印出JVM的内存占用情况 -XX:+ PrintGCDateStamps 记录系统的GC时间 -XX:+PrintGCCause 产生GC的原因(默认开启)
对于很多没用过的人来说,面试官问项目中这些参数是怎么用?此时,很容易选择妥协,傻傻的回答没用过。
偷偷的告诉你,很多面试官也没有用过。
另外,你可以自己搞个小项目,把JVM
参数设置小点,使用测试工具JMeter
,多线程测试一下。
以上是美團面試:熟悉哪些JVM調校參數,幸好我準備過!的詳細內容。更多資訊請關注PHP中文網其他相關文章!