目录
-XX:+PrintCommandLineFlags查看使用的回收器
背景
本文总结一下JVM的一些运行时参数
JVM参数选项类型
标准参数选项
特点
比较稳定,后续版本基本不会变化,以x开头;可以通过java或java -help得到
-server与-client
-client可以设置HotSpot JVM为client模式;-server则将之设置为server模式
32位Windows上默认采用的是Client类型的JVM,若要使用Server模式,则需要有2个及以上个CPU和2G及以上的物理内存;client模式适用于对内存要求较小的桌面应用程序,默认使用Serial串行垃圾回收器。
64位机器上只能支持server模式的JVM,适用于需要大内存的应用程序,默认使用并行垃圾回收器
-X参数选项
特点
非标准化参数,但功能还是比较稳定的,以-X开头
各种选项
通过java -X查看
JVM的JIT编译模式相关
-Xint:禁用编译器,所有字节码被解释执行,此时速度最慢
-Xcomp:所有字节码第一次使用时就被编译成本地代码,然后再执行
-Xmixed:混合模式,也是默认选项,让JIT根据程序运行情况,有选择地将某些代码编译成本地代码
特别地
-Xms、-Xmx、-Xss需要后面紧跟着数值大小和单位,比如-Xmx1024m、-Xms1024k,-Xss512k等;这三个指令分别等价于-XX:InitialHeapSize、-XX:MaxHeapSize、-XX:ThreadStackSize
-XX参数选项
特点
非标准化参数,是我们使用最多的参数类型,属于实验性质,不稳定,以-XX开头,用于开发和调试JVM
分类
1)、Boolean类型格式:
-XX:+<option>表示启用option属性;
-XX:-<option>表示禁用option属性
比如,-XX:+UseParallelGC为选择垃圾回收器为并行回收器,-XX:+UseG1GC为启用G1回收器;-XX:+UseAdaptiveSizePolicy表示自动选择年轻代大小和幸存者区的比例
2)、非Boolean类型格式:
数值类型:-XX:<option>=<number>,number可以带上单位,比如m、M、k、K、g、G,举例有-XX:NewSize=1024M为设置新生代初始大小为1024M、-XX:NewGCPauseMillis=500表示设置GC停顿时间为500ms、-XX:GCTimeRatio=19表示设置吞吐量、-XX:NewRatio=2表示设置新生代与老年代的比例为1:2
非数值类型:-XX:<option>=<string>,比如-XX:HeapDumpPath=D:/mydump.hprof来指定堆转储文件的路径和文件名
特别地
-XX:+PrintFlagsFinal可以输出所有参数名称和默认值,默认不包含Diagnostic个Experimental参数,可以配合-XX:+UnlockDiagnosticVMOptions和-XX:+UnlockExperimentalVMOptions使用
添加JVM参数选项
idea
上方工具栏->Edit Configuration,要确保要运行的类是正确的(此处为OOMTest)
在弹出的窗口中点击Modify options
在弹出的菜单中选择Add VM Options
然后在jdk版本后面加上我们需要的JVM参数就行
完成后点击OK即可生效
运行jar包
C:\Users\songzeceng>java -Xms50m -Xmx50m -XX:+PrintGCDetails -jar my.jar
程序运行过程中
使用jinfo -flag <name>=<value> <pid>设置非Boolean类型的参数
PS C:\WINDOWS\system32> jinfo -flag MaxHeapFreeRatio=60 16444
使用jinfo -flag [+|-]<name> <pid>设置Boolean类型的参数
PS C:\WINDOWS\system32> jinfo -flag +PrintGCDetails 16444
但不是所有的参数都能被运行时修改,能修改的是被标记为manageable的参数
常用的JVM参数选项
打印设置的XX选项及值
-XX:+PrintFlagsInitial
查看所有JVM参数初始值
-XX:+PrintFlagsFinal
查看所有JVM参数最终值
-XX:+PrintCommandLineFlags
查看通过命令行修改的JVM参数名和参数值
-XX:+PrintVMOptions
打印JVM参数
堆、栈、方法区等内存大小设置
堆
-Xms250M设置JVM初始堆内存为250M,等价于-XX:InitialHeapSize=250M
-Xmx250M设置JVM最大堆大小为250M,等价于-XX:MaxHeapSize=250M
-Xmn2G设置年轻代大小为2G,官方推荐设置为整个堆大小的3/8
-XX:NewSize=1024M设置年轻代初始值为1024M
-XX:MaxNewSize=1024M设置年轻代最大值为1024M
-XX:SurvivorRatio=8设置年轻代中伊甸园区与一个幸存者区的大小比值为8:1,
-XX:+UseAdaptiveSizePolicy表示自动选择各区大小比例,默认开启,而为了达到手动调节伊甸园区与一个幸存者区的效果,-XX:-UseAdaptiveSizePolicy和-XX:SurvivorRatio=X最好配合使用
-XX:NewRatio=4设置老年代与年轻代大小的比值为4:1,默认为2:1
-XX:PretenureSizeThredshold=1024表示让大小大于此阈值的对象直接被分配到老年代,单位为字节,此参数只对Serial、ParNew回收器有效
-XX:MaxTenuringThreshold=15表示存活对象在新生代的最大年龄,也就是最多经历过多少次Minor GC后被放入老年代,默认值为15
-XX:+PrintTenuringDistribution表示让JVM每次Minor GC后打印出当前使用的幸存者区中对象的年龄分布
-XX:TargetSurvivorRatio表示Minor GC后幸存者区中占用空间的期望比例
栈
-Xss128K表示设置每个线程的栈大小为128K,等价于-XX:ThreadStackSize=128K
方法区
永久代:
-XX:PermSize=256m设置永久代初始大小为256M;
-XX:MaxPermSize=256M设置永久代最大值为256M
元空间:
-XX:MetaspaceSize=256m设置元空间大小为256m;
-XX:MaxMetaspaceSize=256m设置元空间最大大小为256M,默认值没有限制;
-XX:+UseCompressedOops使用压缩对象指针;
-XX:+UseCompressedClassPointers使用压缩类指针;
-XX:CompressedClassSpaceSize=256m设置Klass元空间大小为256m,默认1G
直接内存
-XX:MaxDirectMemorySize=256m指定直接内存最大大小为256M,默认与java堆最大值一样
OOM相关的选项
-XX:+HeapDumpOutOfMemoryError表示出现OOM时进行堆文件转储
-XX:+HeapDumpBeforeFullGC表示出现Full GC之前进行堆文件转储
-XX:HeapDumpPath=D:/my.hprof指定堆转储文件路径,默认与程序在同一目录下
-XX:OnOutOfMemoryError=D:/test.bat制定一个脚本路径,当OOM发生时去执行它
垃圾回收器相关选项
-XX:+PrintCommandLineFlags查看使用的回收器
Serial回收器
-XX:+UseSerialGC指定年轻代和老年代都使用串行回收器,这是client模式下的默认选项
ParNew回收器
-XX:+UseParNewGC指定使用ParNew回收器,年轻代使用并行回收器,老年代不受影响
-XX:ParallelGCThreads=N限制回收线程数,默认和CPU线程数相等(<8时),或者3 + (5 * CPU_count) / 8(cpu线程数>=8时),向下取整
Parallel回收器
-XX:+UseParallelGC指定年轻代使用Parallel并行收集器
-XX:+UseParallelOldGC指定老年代使用并行收集器,这俩参数一个开启,另一个也会开启
-XX:ParallelGCThreads=N设置年轻代并行收集器的线程数,默认和CPU线程数相等(<8时),或者3 + (5 * CPU_count) / 8(cpu线程数>=8时),向下取整
-XX:MaxGCPauseMillis=100设置GC最大STW时间为100ms,可能会导致收集器调整java堆大小
-XX:GCTimeRatio=N设置GC时间占总时间的比例为1 / (N + 1),和-XX:MaxGCPauseMillis有矛盾性,默认值为99
-XX:+UseAdaptiveSizePolicy设置并收集器的自适应调节策略,默认开启
CMS回收器
-XX:+UseConcMarkSweepGC指定CMS收集器的使用,将自动设置-XX:+UseParNewGC
-XX:CMSInitiatingOccupancyFraction设置堆内存使用率的阈值,一旦达到此阈值,就开始回收,jdk6之前为68,jdk6开始默认为92
-XX:+UseCMSCompactAtFullCollection用于指定在Full GC之后对内存空间进行压缩整理,以避免内存碎片的产生
-XX:CMSFullGCsBeforeCompaction设置在执行多少次Full GC之后对内存空间进行压缩整理
-XX:ParallelCMSThreads设置CMS线程数量,默认值为(ParallelGCThreads + 3) / 4
JDK9中,CMS被标记为废弃;JDK14中,CMS被删除了
G1回收器
-XX:+UseG1GC指定使用G1回收器
-XX:G1HeapRegionSize设置每个分区大小,值应为2的整次幂,范围在1MB到32MB之间,默认是堆内存的1/2000
-XX:MaxGCPauseMillis设置最大GC停顿时间(毫秒),默认200
-XX:ParallelGCThread设置STW是GC线程数,最大为8
-XX:ConcGCThreads设置并发标记的线程数,建议将其设置为-XX:ParallelGCThread的1/4左右
-XX:InitiatingHeapOccupancyPercent设置触发并发GC的java堆占用率阈值,超过此值则触发GC,默认45
-XX:G1NewSizePercent、-XX:G1MaxNewSizePercent设置新生代占整个堆内存的最小和最大百分比,默认值分别是5和60
-XX:G1ReservePercent设置保留内存区域占幸存区的比重,防止幸存区中的to区溢出
如何选择垃圾回收器
优先调整堆的大小让JVM自适应完成;
如果内存<100M,使用串行回收器;
如果是单核单机程序,没有停顿时间要求,使用串行回收器;
如果是多CPU、需要高吞吐量、允许停顿时间超过1s,选择并行或者让JVM自己选择;
如果是多CPU、需要快速响应(比如延迟不超过1s)、追求低停顿时间,适应并发回收器,官方推荐G1
没有最好的、万能的收集器
GC日志相关选项
常用参数
-verbose:gc输出gc日志信息,默认到标准输出
-XX:+PrintGC表示打开简化的GC日志,和上面的指令等同
-XX:+PrintGCDetails在发生垃圾回收时打印详细的GC日志,并在进程退出时输出当前内存各区域的分配情况
-XX:+PrintGCTimeStamps输出GC发生的时间戳,需要和-XX:+PrintGCDetails配合使用
-XX:+PrintGCDateStamps输出GC发生的时间戳,以日期的格式,需要和-XX:+PrintGCDetails配合使用
-XX:+PrintHeapAtGC在每一次的GC前和后,都打印堆信息,可以和-XX:+PrintGCDetails、-XX:+PrintGCDateStamps、-XX:+PrintGCTimeStamps配合使用
-Xloggc:<file>把GC日志写入到一个文件中
其他参数
-XX:+TraceClassLoading监控类的加载
-XX:+PrintGCApplicationStoppedTime打印GC时线程停顿时间
-XX:+PrintGCApplicationConcurrentTime垃圾收集之前打印打印应用未中断的执行时间
-XX:+PrintReferenceGC记录回收了多少种不同类型的引用
-XX:+PrintTenuringDistribution每次MinorGC后打印出当前使用的幸存者区中对象的年龄分布
-XX:+UseGCLogFileRotation启用GC日志文件的自动转储
-XX:NumberOfGCLogFiles=1控制GC日志文件的循环数量
-XX:GCLogFileSize=1M控制GC日志文件大小为1m
其他参数
-XX:+DisableExplicitGC禁止hotspot执行System.gc(),默认禁用
-XX:ReservedCodeCacheSize、-XX:InitialCodeCacheSize指定代码缓存大小与初始大小
-XX:+UseCodeCacheFlushing让JVM放弃一些被编译的代码,避免代码缓存被占满时JVM切换到interpreted-only
-XX:+DoEscapeAnalysis开启逃逸分析
-XX:+UseBiasedLocking开启偏向锁
-XX:+UseLargePages开启使用大页面
-XX:+UseTLAB使用TLAB,默认打开
-XX:+PrintTLAB打印TLAB的使用情况
-XX:TLABSize设置TLAB大小
通过java代码获取JVM参数
通过Runtime或者ManagementFactory获取
结语
下一篇文章将对GC日志进行分析,终结JVM学习笔记