JVM之_7_调优参数和命令
前言
Github:https://github.com/HealerJean
一、JVM 参数
1、项目使用
1)XM
"http_port=8391
server_port=8392
jvm_args='-Xmn256M -Xmx1024M -Xms1024M -XX:MaxPermSize=256M -XX:PermSize=256M -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC -XX:CMSFullGCsBeforeCompaction=50 -XX:+UseCMSCompactAtFullCollection -XX:MaxTenuringThreshold=10 -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintFlagsFinal -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8393 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Xloggc:/usr/local/service/log/scf/scf-manager/gc.log -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=19137 -Dlog4j2.isThreadContextMapInheritable=true'"
-Xmn256M -Xmx1024M -Xms1024M
-XX:MaxPermSize=256M -XX:PermSize=256M -XX:SurvivorRatio=8
-XX:+UseConcMarkSweepGC //使用CMS
-XX:CMSFullGCsBeforeCompaction=50 // 多少次FULL GC 后压缩老年代
-XX:+UseCMSCompactAtFullCollection // UseCMSCompactAtFullCollection 是否压缩,默认true
-XX:MaxTenuringThreshold=10 //老年代最大年龄
-verbose:gc //打印GC日志
-XX:+PrintGCDetails //输出GC的详细日志
-XX:+PrintGCTimeStamps //日志钱打印时间戳
-XX:+PrintGCDateStamps //打印日期
-XX:+PrintFlagsFinal //打印所有的系统参数的值(
-Dcom.sun.management.jmxremote //JVM监控
-Dcom.sun.management.jmxremote.port=8393
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Xloggc:/usr/local/service/log/scf/scf-manager/gc.log //日志文件的输出路径
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=19137
-Dlog4j2.isThreadContextMapInheritable=true
class c4 inherits base {
$jvm_args = ["-Xmn512M", "-Xmx4096M", "-Xms4096M", "-XX:MaxMetaspaceSize=256M", "-XX:MetaspaceSize=256M", "-XX:MaxPermSize=256M", "-XX:PermSize=256M", "-XX:SurvivorRatio=8",
"-XX:+UseConcMarkSweepGC", "-XX:CMSFullGCsBeforeCompaction=50", "-XX:+UseCMSCompactAtFullCollection", "-Duse.local.proxy=false",
"-XX:MaxTenuringThreshold=10", "-verbose:gc", "-XX:+PrintGCDetails", "-XX:+PrintGCTimeStamps", "-XX:+PrintGCDateStamps", "-XX:+PrintFlagsFinal", "-Dcom.sun.management.jmxremote", "-Dcom.sun.management.jmxremote.port=${jmx_port}", "-Dcom.sun.management.jmxremote.ssl=false", "-Dcom.sun.management.jmxremote.authenticate=false", "-Xloggc:${log_dir}/gc.log",
"-Dcom.sun.management.jmxremote.host=127.0.0.1","-Djava.rmi.server.hostname=127.0.0.1"]
}
class staging inherits base {
$jvm_args = ["-Xmn256M", "-Xmx1024M", "-Xms1024M", "-XX:MaxPermSize=256M", "-XX:PermSize=256M", "-XX:SurvivorRatio=8",
"-XX:+UseConcMarkSweepGC", "-XX:CMSFullGCsBeforeCompaction=50", "-XX:+UseCMSCompactAtFullCollection",
"-XX:MaxTenuringThreshold=10", "-verbose:gc", "-XX:+PrintGCDetails", "-XX:+PrintGCTimeStamps", "-XX:+PrintGCDateStamps",
"-XX:+PrintFlagsFinal", "-Dcom.sun.management.jmxremote", "-Dcom.sun.management.jmxremote.port=${jmx_port}",
"-Dcom.sun.management.jmxremote.ssl=false", "-Dcom.sun.management.jmxremote.authenticate=false",
"-Xloggc:${log_dir}/gc.log","-Dlog4j2.isThreadContextMapInheritable=true",
"-Dcom.sun.management.jmxremote.host=127.0.0.1","-Djava.rmi.server.hostname=127.0.0.1"]
}
2)MT
-Dfile.encoding=UTF-8
-Dsun.jnu.encoding=UTF-8
-Djava.io.tmpdir=/tmp
-Djava.net.preferIPv6Addresses=false
-Djava.io.tmpdir=/tmp
-Duser.timezone=GMT+08
-Xss512k -Xmx4096m -Xms4096m
-XX:MetaspaceSize=512m
-XX:MaxMetaspaceSize=512m
-XX:+AlwaysPreTouch
-XX:+HeapDumpOnOutOfMemoryError
-XX:+UseG1GC
-XX:G1HeapRegionSize=4M
-XX:InitiatingHeapOccupancyPercent=40
-XX:MaxGCPauseMillis=100
-XX:+TieredCompilation
-XX:=4
-XX:-UseBiasedLocking
-XX:+PrintGCDetails
-XX:+PrintHeapAtGC
-XX:+PrintTenuringDistribution
-XX:+PrintGCTimeStamps
-XX:+PrintGCDateStamps
-XX:+PrintStringTableStatistics
-XX:+PrintAdaptiveSizePolicy
-XX:+PrintGCApplicationStoppedTime
-XX:+PrintFlagsFinal
-XX:-UseGCLogFileRotation
-XX:NumberOfGCLogFiles=10
-XX:GCLogFileSize=10M
-Xloggc:/var/sankuai/logs/com.sankuai.windmill.riding.facadeapi/gc.log.20210728
-XX:ErrorFile=/var/sankuai/logs/com.sankuai.windmill.riding.facadeapi/vmerr.log.20210728
-XX:HeapDumpPath=/var/sankuai/logs/com.sankuai.windmill.riding.facadeapi/heaperr.log.20210728
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8418
-javaagent:/opt/meituan/qa_test/jacocoagent.jar=output=tcpserver,port=6300,address=*,excludes=com.dianping.*
-Dspring.profiles.active=test -jar ./facade-api-1.0.0.jar
3)JD
export maxParameterCount="1000"
export acceptCount="1000"
export maxSpareThreads="750"
export maxThreads="1000"
export minSpareThreads="50"
export URIEncoding="UTF-8"
export JAVA_OPTS=" -Xms13312m -Xmx13312m -XX:G1HeapRegionSize=4m -XX:MaxMetaspaceSize=512m -XX:MetaspaceSize=512m -XX:MaxDirectMemorySize=512m -XX:ConcGCThreads=4 -XX:ParallelGCThreads=8 -XX:MaxGCPauseMillis=100 -XX:InitiatingHeapOccupancyPercent=65 -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDetails -XX:HeapDumpPath=/export/Logs -XX:+PrintGCDateStamps -Xloggc:/export/Logs/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=10M -Djava.library.path=/usr/local/lib -server -XX:+UseG1GC -XX:HeapDumpPath=/export/Logs -Djava.awt.headless=true -Dsun.net.client.defaultConnectTimeout=60000 -Dsun.net.client.defaultReadTimeout=60000 -Djmagick.systemclassloader=no "
二、参数说明
1、GC 日志查看
| 参数 | 说明 |
|---|---|
-XX:+PrintGC |
输出GC日志 |
-XX:+PrintGCDetails |
输出GC的详细日志,打印每次垃圾回收的详细信息,包括年轻代、老年代的内存变化等。 |
-XX:+PrintGCTimeStamps |
输出GC的时间戳(以基准时间的形式,便于追溯时间点) |
-XX:+PrintGCDateStamps: |
在 GC 日志中添加时间戳(以日期的形式,便于追溯时间点)。 |
-Xloggc:/export/Logs/gc.log: |
指定 GC 日志输出路径及文件名。 |
-XX:+UseGCLogFileRotation |
启用 GC 日志轮转(避免单文件过大)。 |
-XX:NumberOfGCLogFiles=5: |
最多保留 5 个日志文件。 |
-XX:GCLogFileSize=10M: |
单个日志文件达到 10M 时自动轮转。 |
-XX:+PrintHeapAtGC |
在进行 GC 的前后打印出堆的信息 |
-Xloggc: |
../logs/gc.log 日志文件的输出路径 |
1)-XX:+PrintGC 和 -verbose:gc
输出
GC日志:-XX:+PrintGC与-verbose:gc是一样的,可以认为-verbose:gc是-XX:+PrintGC的别名注意:
PrintGC必须开启,只开启PrintGCDetails、PrintGCTimeStamps不会输出GC,必须PrintGC同时开启,一般情况下,配置了其他的,-XX:+PrintGC会被自动打开
-Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8
-verbose:gc
[GC (System.gc()) 2635K->1065K(19456K), 0.0017115 secs]
[Full GC (System.gc()) 1065K->917K(19456K), 0.0047886 secs]
-Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8
-XX:+PrintG
[GC (System.gc()) 2635K->1040K(19456K), 0.0013182 secs]
[Full GC (System.gc()) 1040K->917K(19456K), 0.0053261 secs]
| 参数 | 默认值 | 用法 |
|---|---|---|
-verbose: |
无 | 在输出设备上显示虚拟机运行信息 |
verbose:class |
在程序运行的时候有多少类被加载!可以用verbose:class来监视 | |
verbose:gc |
在虚拟机发生内存回收时在输出设备显示信息,格式如下: [Full GC 256K->160K(124096K), 0.0042708 secs] 该参数用来监视虚拟机内存回收的情况。 | |
verbose:jni |
输出native方法调用的相关情况,一般用于诊断jni调用错误信息。 |
2)-XX:+PrintGCDetails
输出
GC的详细日志
-Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8 -
verbose:gc
-XX:+PrintGCDetails
[GC (System.gc()) [PSYoungGen: 2635K->1008K(9216K)] 2635K->1158K(19456K), 0.0013864 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (System.gc()) [PSYoungGen: 1008K->0K(9216K)] [ParOldGen: 150K->918K(10240K)] 1158K->918K(19456K), [Metaspace: 3218K->3218K(1056768K)], 0.0054385 secs] [Times: user=0.09 sys=0.00, real=0.01 secs]
Heap
PSYoungGen total 9216K, used 246K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
eden space 8192K, 3% used [0x00000000ff600000,0x00000000ff63d8e0,0x00000000ffe00000)
from space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
to space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
ParOldGen total 10240K, used 918K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
object space 10240K, 8% used [0x00000000fec00000,0x00000000fece5b50,0x00000000ff600000)
Metaspace used 3234K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 309K, capacity 388K, committed 512K, reserved 1048576K
3)-XX:+PrintGCTimeStamps
输出GC的时间戳(以基准时间的形式:
-XX:+PrintGCTimeStamps)
-Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8
-verbose:gc
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
0.313: [GC (System.gc()) [PSYoungGen: 2635K->1008K(9216K)] 2635K->1122K(19456K), 0.0011256 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
0.315: [Full GC (System.gc()) [PSYoungGen: 1008K->0K(9216K)] [ParOldGen: 114K->918K(10240K)] 1122K->918K(19456K), [Metaspace: 3222K->3222K(1056768K)], 0.0051251 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Heap
PSYoungGen total 9216K, used 246K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
eden space 8192K, 3% used [0x00000000ff600000,0x00000000ff63d888,0x00000000ffe00000)
from space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
to space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
ParOldGen total 10240K, used 918K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
object space 10240K, 8% used [0x00000000fec00000,0x00000000fece59a8,0x00000000ff600000)
Metaspace used 3245K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 311K, capacity 388K, committed 512K, reserved 1048576K
4)-XX:+PrintGCDateStamps
输出GC的日期
-Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8 -verbose:gc -XX:+PrintGCDetails
-XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps
2019-12-24T11:34:45.910+0800: 0.343: [GC (System.gc()) [PSYoungGen: 2635K->1008K(9216K)] 2635K->1158K(19456K), 0.0018725 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
2019-12-24T11:34:45.912+0800: 0.345: [Full GC (System.gc()) [PSYoungGen: 1008K->0K(9216K)] [ParOldGen: 150K->917K(10240K)] 1158K->917K(19456K), [Metaspace: 3206K->3206K(1056768K)], 0.0053643 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
Heap
PSYoungGen total 9216K, used 82K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
eden space 8192K, 1% used [0x00000000ff600000,0x00000000ff614920,0x00000000ffe00000)
from space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
to space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
ParOldGen total 10240K, used 917K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
object space 10240K, 8% used [0x00000000fec00000,0x00000000fece54d0,0x00000000ff600000)
Metaspace used 3213K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 304K, capacity 388K, committed 512K, reserved 1048576K
5)-XX:-OmitStackTraceInFastThrow
参数可以防止
JVM在FastThrow优化中省略异常堆栈信息。说明:在
Java虚拟机(JVM)中,为了提高性能,当检测到某个位置连续多次抛出同一类型的异常时,JVM会采用Fast Throw优化机制。这种机制会省略异常的详细堆栈信息,直接抛出一个预先分配好的、类型匹配的对象,这个对象的message和stack trace都被清空。这样做的目的是减少不必要的内存分配和栈信息构造,从而提高程序的运行效率。然而,这也可能导致在调试和定位问题时缺少关键的堆栈信息。注意:禁用
FastThrow优化可能会稍微降低程序的性能,因为JVM需要分配内存并构造完整的异常栈信息。然而,在调试和定位问题的过程中,保留完整的堆栈信息通常比性能优化更为重要。因此,在开发和测试阶段,启用-XX:-OmitStackTraceInFastThrow参数是有帮助的。但在生产环境中,你需要权衡性能和调试信息之间的需求。
6)-XX:+PrintHeapAtGC
在进行
GC的前后打印出堆的信息(-XX:+PrintHeapAtGC:)
-Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8
-verbose:gc
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+PrintGCTimeStamps
-XX:+PrintHeapAtGC
{Heap before GC invocations=1 (full 0):
PSYoungGen total 9216K, used 2635K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
eden space 8192K, 32% used [0x00000000ff600000,0x00000000ff892dc8,0x00000000ffe00000)
from space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
to space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
ParOldGen total 10240K, used 0K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
object space 10240K, 0% used [0x00000000fec00000,0x00000000fec00000,0x00000000ff600000)
Metaspace used 3206K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 304K, capacity 388K, committed 512K, reserved 1048576K
2019-12-24T13:48:42.020+0800: 0.384: [GC (System.gc()) [PSYoungGen: 2635K->1016K(9216K)] 2635K->1100K(19456K), 0.0010979 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Heap after GC invocations=1 (full 0):
PSYoungGen total 9216K, used 1016K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
eden space 8192K, 0% used [0x00000000ff600000,0x00000000ff600000,0x00000000ffe00000)
from space 1024K, 99% used [0x00000000ffe00000,0x00000000ffefe010,0x00000000fff00000)
to space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
ParOldGen total 10240K, used 84K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
object space 10240K, 0% used [0x00000000fec00000,0x00000000fec15240,0x00000000ff600000)
Metaspace used 3206K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 304K, capacity 388K, committed 512K, reserved 1048576K
}
{Heap before GC invocations=2 (full 1):
PSYoungGen total 9216K, used 1016K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
eden space 8192K, 0% used [0x00000000ff600000,0x00000000ff600000,0x00000000ffe00000)
from space 1024K, 99% used [0x00000000ffe00000,0x00000000ffefe010,0x00000000fff00000)
to space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
ParOldGen total 10240K, used 84K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
object space 10240K, 0% used [0x00000000fec00000,0x00000000fec15240,0x00000000ff600000)
Metaspace used 3206K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 304K, capacity 388K, committed 512K, reserved 1048576K
2019-12-24T13:48:42.021+0800: 0.385: [Full GC (System.gc()) [PSYoungGen: 1016K->0K(9216K)] [ParOldGen: 84K->917K(10240K)] 1100K->917K(19456K), [Metaspace: 3206K->3206K(1056768K)], 0.0049082 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
Heap after GC invocations=2 (full 1):
PSYoungGen total 9216K, used 0K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
eden space 8192K, 0% used [0x00000000ff600000,0x00000000ff600000,0x00000000ffe00000)
from space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
to space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
ParOldGen total 10240K, used 917K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
object space 10240K, 8% used [0x00000000fec00000,0x00000000fece54d0,0x00000000ff600000)
Metaspace used 3206K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 304K, capacity 388K, committed 512K, reserved 1048576K
}
Heap
PSYoungGen total 9216K, used 246K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
eden space 8192K, 3% used [0x00000000ff600000,0x00000000ff63d890,0x00000000ffe00000)
from space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
to space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
ParOldGen total 10240K, used 917K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
object space 10240K, 8% used [0x00000000fec00000,0x00000000fece54d0,0x00000000ff600000)
Metaspace used 3222K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 306K, capacity 388K, committed 512K, reserved 1048576K
7) -XX:+PrintTenuringDistribution
打印出
Survivor空间中的对象的年龄分布(-XX:+PrintTenuringDistribution:)打印对象晋升到老年代的年龄分布信息,有助于了解对象的生命周期
-XX:+PrintTenuringDistribution
| 字段 | 含义 |
|---|---|
Desired survivor size |
当前 G1 设定的 Survivor 总容量目标 |
new threshold |
对象晋升老年代所需的最小 GC 次数(年龄阈值) |
age N |
经历了 N 次 GC 还存活的对象大小 |
Desired survivor size 75497472 bytes, new threshold 15 (max 15)
- age 1: 19321624 bytes, 19321624 total
- age 2: 79376 bytes, 19401000 total
- age 3: 2904256 bytes, 22305256 total
从第一行中可以看出JVM期望的Survivor空间占用为72M,对象被移到老年代中的年龄阈值为15。其中期望的Survivor空间大小为Survivor空间大小 x -XX:TargetSurvivorRatio的值。
年龄为1的对象约19M,年龄为2的对象约79k,年龄为3的对象约为 2.9M,每行后面的数值表示所有小于等于该行年龄的对象的总共大小
比如:,比如最后一行就表示所有年龄小于等于3的对象的总共大小为约22M(等于所有年龄对象大小的和)。因为目前Survivor空间中对象的大小22M小于期望Survivor空间的大小72M,所以没有对象会被移到老年代。
性能影响:(几乎可忽略)对吞吐和延迟影响 < 0.1%,可以长期开启用于监控。
JVM在每次YoungGC时本来就要统计对象年龄- 打印这些信息只是“把已有数据写到日志”,不增加额外计算开销
- 日志体积略有增加(每秒一次
GC就多几行文本)
使用建议:
| 场景 | 是否推荐启用 |
|---|---|
| 排查“过早晋升”(Premature Promotion) | ✔️ 强烈推荐 |
| 调优 G1 年轻代大小 | ✔️ 推荐 |
| 分析对象生命周期 | ✔️ 推荐 |
| 生产环境日常监控 | ⚠️ 建议关闭(避免日志过多) |
高频 GC 环境(>10次/秒) |
⚠️ 谨慎开启,防止日志爆炸 |
8)-XX:+PrintFlagsFinal
打印所有的系统参数的值
java -XX:+PrintFlagsFinal -version | grep MetaspaceSiz
-Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8
-verbose:gc
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+PrintGCTimeStamps
-XX:+PrintFlagsFinal
[Global flags]
intx ActiveProcessorCount = -1 {product}
uintx AdaptiveSizeDecrementScaleFactor = 4 {product}
uintx AdaptiveSizeMajorGCDecayTimeScale = 10 {product}
uintx AdaptiveSizePausePolicy = 0 {product}
uintx AdaptiveSizePolicyCollectionCostMargin = 50 {product}
uintx AdaptiveSizePolicyInitializingSteps = 20 {product}
uintx AdaptiveSizePolicyOutputInterval = 0 {product}
uintx AdaptiveSizePolicyWeight = 10 {product}
uintx AdaptiveSizeThroughPutPolicy = 0 {product}
uintx AdaptiveTimeWeight = 25 {product}
bool AdjustConcurrency = false {product}
bool AggressiveHeap = false {product}
bool AggressiveOpts = false {product}
intx AliasLevel = 3 {C2 product}
bool AlignVector = false {C2 product}
intx AllocateInstancePrefetchLines = 1 {product}
intx AllocatePrefetchDistance = 192 {product}
intx AllocatePrefetchInstr = 3 {product}
intx AllocatePrefetchLines = 4 {product}
intx AllocatePrefetchStepSize = 64 {product}
intx AllocatePrefetchStyle = 1 {product}
bool AllowJNIEnvProxy = false {product}
bool AllowNonVirtualCalls = false {product}
bool AllowParallelDefineClass = false {product}
bool AllowUserSignalHandlers = false {product}
bool AlwaysActAsServerClassMachine = false {product}
bool AlwaysCompileLoopMethods = false {product}
bool AlwaysLockClassLoader = false {product}
bool AlwaysPreTouch = false {product}
bool AlwaysRestoreFPU = false {product}
bool AlwaysTenure = false {product}
bool AssertOnSuspendWaitFailure = false {product}
bool AssumeMP = false {product}
intx AutoBoxCacheMax = 128 {C2 product}
uintx AutoGCSelectPauseMillis = 5000 {product}
intx BCEATraceLevel = 0 {product}
intx BackEdgeThreshold = 100000 {pd product}
bool BackgroundCompilation = true {pd product}
uintx BaseFootPrintEstimate = 268435456 {product}
intx BiasedLockingBulkRebiasThreshold = 20 {product}
intx BiasedLockingBulkRevokeThreshold = 40 {product}
intx BiasedLockingDecayTime = 25000 {product}
intx BiasedLockingStartupDelay = 4000 {product}
bool BindGCTaskThreadsToCPUs = false {product}
bool BlockLayoutByFrequency = true {C2 product}
intx BlockLayoutMinDiamondPercentage = 20 {C2 product}
bool BlockLayoutRotateLoops = true {C2 product}
bool BranchOnRegister = false {C2 product}
bool BytecodeVerificationLocal = false {product}
bool BytecodeVerificationRemote = true {product}
bool C1OptimizeVirtualCallProfiling = true {C1 product}
bool C1ProfileBranches = true {C1 product}
bool C1ProfileCalls = true {C1 product}
bool C1ProfileCheckcasts = true {C1 product}
bool C1ProfileInlinedCalls = true {C1 product}
bool C1ProfileVirtualCalls = true {C1 product}
bool C1UpdateMethodData = true {C1 product}
intx CICompilerCount := 4 {product}
bool CICompilerCountPerCPU = true {product}
bool CITime = false {product}
bool CMSAbortSemantics = false {product}
uintx CMSAbortablePrecleanMinWorkPerIteration = 100 {product}
intx CMSAbortablePrecleanWaitMillis = 100 {manageable}
uintx CMSBitMapYieldQuantum = 10485760 {product}
uintx CMSBootstrapOccupancy = 50 {product}
bool CMSClassUnloadingEnabled = true {product}
uintx CMSClassUnloadingMaxInterval = 0 {product}
bool CMSCleanOnEnter = true {product}
bool CMSCompactWhenClearAllSoftRefs = true {product}
uintx CMSConcMarkMultiple = 32 {product}
bool CMSConcurrentMTEnabled = true {product}
uintx CMSCoordinatorYieldSleepCount = 10 {product}
bool CMSDumpAtPromotionFailure = false {product}
bool CMSEdenChunksRecordAlways = true {product}
uintx CMSExpAvgFactor = 50 {product}
bool CMSExtrapolateSweep = false {product}
uintx CMSFullGCsBeforeCompaction = 0 {product}
uintx CMSIncrementalDutyCycle = 10 {product}
uintx CMSIncrementalDutyCycleMin = 0 {product}
bool CMSIncrementalMode = false {product}
uintx CMSIncrementalOffset = 0 {product}
bool CMSIncrementalPacing = true {product}
uintx CMSIncrementalSafetyFactor = 10 {product}
uintx CMSIndexedFreeListReplenish = 4 {product}
intx CMSInitiatingOccupancyFraction = -1 {product}
uintx CMSIsTooFullPercentage = 98 {product}
double CMSLargeCoalSurplusPercent = 0.950000 {product}
double CMSLargeSplitSurplusPercent = 1.000000 {product}
bool CMSLoopWarn = false {product}
uintx CMSMaxAbortablePrecleanLoops = 0 {product}
intx CMSMaxAbortablePrecleanTime = 5000 {product}
uintx CMSOldPLABMax = 1024 {product}
uintx CMSOldPLABMin = 16 {product}
uintx CMSOldPLABNumRefills = 4 {product}
uintx CMSOldPLABReactivityFactor = 2 {product}
bool CMSOldPLABResizeQuicker = false {product}
uintx CMSOldPLABToleranceFactor = 4 {product}
bool CMSPLABRecordAlways = true {product}
uintx CMSParPromoteBlocksToClaim = 16 {product}
bool CMSParallelInitialMarkEnabled = true {product}
bool CMSParallelRemarkEnabled = true {product}
bool CMSParallelSurvivorRemarkEnabled = true {product}
uintx CMSPrecleanDenominator = 3 {product}
uintx CMSPrecleanIter = 3 {product}
uintx CMSPrecleanNumerator = 2 {product}
bool CMSPrecleanRefLists1 = true {product}
bool CMSPrecleanRefLists2 = false {product}
bool CMSPrecleanSurvivors1 = false {product}
bool CMSPrecleanSurvivors2 = true {product}
uintx CMSPrecleanThreshold = 1000 {product}
bool CMSPrecleaningEnabled = true {product}
bool CMSPrintChunksInDump = false {product}
bool CMSPrintEdenSurvivorChunks = false {product}
bool CMSPrintObjectsInDump = false {product}
uintx CMSRemarkVerifyVariant = 1 {product}
bool CMSReplenishIntermediate = true {product}
uintx CMSRescanMultiple = 32 {product}
uintx CMSSamplingGrain = 16384 {product}
bool CMSScavengeBeforeRemark = false {product}
uintx CMSScheduleRemarkEdenPenetration = 50 {product}
uintx CMSScheduleRemarkEdenSizeThreshold = 2097152 {product}
uintx CMSScheduleRemarkSamplingRatio = 5 {product}
double CMSSmallCoalSurplusPercent = 1.050000 {product}
double CMSSmallSplitSurplusPercent = 1.100000 {product}
bool CMSSplitIndexedFreeListBlocks = true {product}
intx CMSTriggerInterval = -1 {manageable}
uintx CMSTriggerRatio = 80 {product}
intx CMSWaitDuration = 2000 {manageable}
uintx CMSWorkQueueDrainThreshold = 10 {product}
bool CMSYield = true {product}
uintx CMSYieldSleepCount = 0 {product}
uintx CMSYoungGenPerWorker = 67108864 {pd product}
uintx CMS_FLSPadding = 1 {product}
uintx CMS_FLSWeight = 75 {product}
uintx CMS_SweepPadding = 1 {product}
uintx CMS_SweepTimerThresholdMillis = 10 {product}
uintx CMS_SweepWeight = 75 {product}
bool CheckEndorsedAndExtDirs = false {product}
bool CheckJNICalls = false {product}
bool ClassUnloading = true {product}
bool ClassUnloadingWithConcurrentMark = true {product}
intx ClearFPUAtPark = 0 {product}
bool ClipInlining = true {product}
uintx CodeCacheExpansionSize = 65536 {pd product}
uintx CodeCacheMinimumFreeSpace = 512000 {product}
bool CollectGen0First = false {product}
bool CompactFields = true {product}
intx CompilationPolicyChoice = 3 {product}
ccstrlist CompileCommand = {product}
ccstr CompileCommandFile = {product}
ccstrlist CompileOnly = {product}
intx CompileThreshold = 10000 {pd product}
bool CompilerThreadHintNoPreempt = true {product}
intx CompilerThreadPriority = -1 {product}
intx CompilerThreadStackSize = 0 {pd product}
uintx CompressedClassSpaceSize = 1073741824 {product}
uintx ConcGCThreads = 0 {product}
intx ConditionalMoveLimit = 3 {C2 pd product}
intx ContendedPaddingWidth = 128 {product}
bool ConvertSleepToYield = true {pd product}
bool ConvertYieldToSleep = false {product}
bool CrashOnOutOfMemoryError = false {product}
bool CreateMinidumpOnCrash = false {product}
bool CriticalJNINatives = true {product}
bool DTraceAllocProbes = false {product}
bool DTraceMethodProbes = false {product}
bool DTraceMonitorProbes = false {product}
bool Debugging = false {product}
uintx DefaultMaxRAMFraction = 4 {product}
intx DefaultThreadPriority = -1 {product}
intx DeferPollingPageLoopCount = -1 {product}
intx DeferThrSuspendLoopCount = 4000 {product}
bool DeoptimizeRandom = false {product}
bool DisableAttachMechanism = false {product}
bool DisableExplicitGC = false {product}
bool DisplayVMOutputToStderr = false {product}
bool DisplayVMOutputToStdout = false {product}
bool DoEscapeAnalysis = true {C2 product}
bool DontCompileHugeMethods = true {product}
bool DontYieldALot = false {pd product}
ccstr DumpLoadedClassList = {product}
bool DumpReplayDataOnError = true {product}
bool DumpSharedSpaces = false {product}
bool EagerXrunInit = false {product}
intx EliminateAllocationArraySizeLimit = 64 {C2 product}
bool EliminateAllocations = true {C2 product}
bool EliminateAutoBox = true {C2 product}
bool EliminateLocks = true {C2 product}
bool EliminateNestedLocks = true {C2 product}
intx EmitSync = 0 {product}
bool EnableContended = true {product}
bool EnableTracing = false {product}
uintx ErgoHeapSizeLimit = 0 {product}
ccstr ErrorFile = {product}
ccstr ErrorReportServer = {product}
double EscapeAnalysisTimeout = 20.000000 {C2 product}
bool EstimateArgEscape = true {product}
bool ExitOnOutOfMemoryError = false {product}
bool ExplicitGCInvokesConcurrent = false {product}
bool ExplicitGCInvokesConcurrentAndUnloadsClasses = false {product}
bool ExtendedDTraceProbes = false {product}
ccstr ExtraSharedClassListFile = {product}
bool FLSAlwaysCoalesceLarge = false {product}
uintx FLSCoalescePolicy = 2 {product}
double FLSLargestBlockCoalesceProximity = 0.990000 {product}
bool FailOverToOldVerifier = true {product}
bool FastTLABRefill = true {product}
intx FenceInstruction = 0 {ARCH product}
intx FieldsAllocationStyle = 1 {product}
bool FilterSpuriousWakeups = true {product}
bool ForceNUMA = false {product}
bool ForceTimeHighResolution = false {product}
intx FreqInlineSize = 325 {pd product}
double G1ConcMarkStepDurationMillis = 10.000000 {product}
uintx G1ConcRSHotCardLimit = 4 {product}
uintx G1ConcRSLogCacheSize = 10 {product}
intx G1ConcRefinementGreenZone = 0 {product}
intx G1ConcRefinementRedZone = 0 {product}
intx G1ConcRefinementServiceIntervalMillis = 300 {product}
uintx G1ConcRefinementThreads = 0 {product}
intx G1ConcRefinementThresholdStep = 0 {product}
intx G1ConcRefinementYellowZone = 0 {product}
uintx G1ConfidencePercent = 50 {product}
uintx G1HeapRegionSize = 0 {product}
uintx G1HeapWastePercent = 5 {product}
uintx G1MixedGCCountTarget = 8 {product}
intx G1RSetRegionEntries = 0 {product}
uintx G1RSetScanBlockSize = 64 {product}
intx G1RSetSparseRegionEntries = 0 {product}
intx G1RSetUpdatingPauseTimePercent = 10 {product}
intx G1RefProcDrainInterval = 10 {product}
uintx G1ReservePercent = 10 {product}
uintx G1SATBBufferEnqueueingThresholdPercent = 60 {product}
intx G1SATBBufferSize = 1024 {product}
intx G1UpdateBufferSize = 256 {product}
bool G1UseAdaptiveConcRefinement = true {product}
uintx GCDrainStackTargetSize = 64 {product}
uintx GCHeapFreeLimit = 2 {product}
uintx GCLockerEdenExpansionPercent = 5 {product}
bool GCLockerInvokesConcurrent = false {product}
uintx GCLogFileSize = 8192 {product}
uintx GCPauseIntervalMillis = 0 {product}
uintx GCTaskTimeStampEntries = 200 {product}
uintx GCTimeLimit = 98 {product}
uintx GCTimeRatio = 99 {product}
uintx HeapBaseMinAddress = 2147483648 {pd product}
bool HeapDumpAfterFullGC = false {manageable}
bool HeapDumpBeforeFullGC = false {manageable}
bool HeapDumpOnOutOfMemoryError = false {manageable}
ccstr HeapDumpPath = {manageable}
uintx HeapFirstMaximumCompactionCount = 3 {product}
uintx HeapMaximumCompactionInterval = 20 {product}
uintx HeapSizePerGCThread = 87241520 {product}
bool IgnoreEmptyClassPaths = false {product}
bool IgnoreUnrecognizedVMOptions = false {product}
uintx IncreaseFirstTierCompileThresholdAt = 50 {product}
bool IncrementalInline = true {C2 product}
uintx InitialBootClassLoaderMetaspaceSize = 4194304 {product}
uintx InitialCodeCacheSize = 2555904 {pd product}
uintx InitialHeapSize := 20971520 {product}
uintx InitialRAMFraction = 64 {product}
double InitialRAMPercentage = 1.562500 {product}
uintx InitialSurvivorRatio = 10 {product}
uintx InitialTenuringThreshold = 7 {product}
uintx InitiatingHeapOccupancyPercent = 45 {product}
bool Inline = true {product}
ccstr InlineDataFile = {product}
intx InlineSmallCode = 2000 {pd product}
bool InlineSynchronizedMethods = true {C1 product}
bool InsertMemBarAfterArraycopy = true {C2 product}
intx InteriorEntryAlignment = 16 {C2 pd product}
intx InterpreterProfilePercentage = 33 {product}
bool JNIDetachReleasesMonitors = true {product}
bool JavaMonitorsInStackTrace = true {product}
intx JavaPriority10_To_OSPriority = -1 {product}
intx JavaPriority1_To_OSPriority = -1 {product}
intx JavaPriority2_To_OSPriority = -1 {product}
intx JavaPriority3_To_OSPriority = -1 {product}
intx JavaPriority4_To_OSPriority = -1 {product}
intx JavaPriority5_To_OSPriority = -1 {product}
intx JavaPriority6_To_OSPriority = -1 {product}
intx JavaPriority7_To_OSPriority = -1 {product}
intx JavaPriority8_To_OSPriority = -1 {product}
intx JavaPriority9_To_OSPriority = -1 {product}
bool LIRFillDelaySlots = false {C1 pd product}
uintx LargePageHeapSizeThreshold = 134217728 {product}
uintx LargePageSizeInBytes = 0 {product}
bool LazyBootClassLoader = true {product}
intx LiveNodeCountInliningCutoff = 40000 {C2 product}
intx LoopMaxUnroll = 16 {C2 product}
intx LoopOptsCount = 43 {C2 product}
intx LoopUnrollLimit = 60 {C2 pd product}
intx LoopUnrollMin = 4 {C2 product}
bool LoopUnswitching = true {C2 product}
bool ManagementServer = false {product}
uintx MarkStackSize = 4194304 {product}
uintx MarkStackSizeMax = 536870912 {product}
uintx MarkSweepAlwaysCompactCount = 4 {product}
uintx MarkSweepDeadRatio = 1 {product}
intx MaxBCEAEstimateLevel = 5 {product}
intx MaxBCEAEstimateSize = 150 {product}
uintx MaxDirectMemorySize = 0 {product}
bool MaxFDLimit = true {product}
uintx MaxGCMinorPauseMillis = 4294967295 {product}
uintx MaxGCPauseMillis = 4294967295 {product}
uintx MaxHeapFreeRatio = 100 {manageable}
uintx MaxHeapSize := 20971520 {product}
intx MaxInlineLevel = 9 {product}
intx MaxInlineSize = 35 {product}
intx MaxJNILocalCapacity = 65536 {product}
intx MaxJavaStackTraceDepth = 1024 {product}
intx MaxJumpTableSize = 65000 {C2 product}
intx MaxJumpTableSparseness = 5 {C2 product}
intx MaxLabelRootDepth = 1100 {C2 product}
intx MaxLoopPad = 11 {C2 product}
uintx MaxMetaspaceExpansion = 5451776 {product}
uintx MaxMetaspaceFreeRatio = 70 {product}
uintx MaxMetaspaceSize = 4294901760 {product}
uintx MaxNewSize := 10485760 {product}
intx MaxNodeLimit = 75000 {C2 product}
uint64_t MaxRAM = 0 {pd product}
uintx MaxRAMFraction = 4 {product}
double MaxRAMPercentage = 25.000000 {product}
intx MaxRecursiveInlineLevel = 1 {product}
uintx MaxTenuringThreshold = 15 {product}
intx MaxTrivialSize = 6 {product}
intx MaxVectorSize = 32 {C2 product}
uintx MetaspaceSize = 21807104 {pd product}
bool MethodFlushing = true {product}
uintx MinHeapDeltaBytes := 524288 {product}
uintx MinHeapFreeRatio = 0 {manageable}
intx MinInliningThreshold = 250 {product}
intx MinJumpTableSize = 10 {C2 pd product}
uintx MinMetaspaceExpansion = 339968 {product}
uintx MinMetaspaceFreeRatio = 40 {product}
uintx MinRAMFraction = 2 {product}
double MinRAMPercentage = 50.000000 {product}
uintx MinSurvivorRatio = 10 {product}
uintx MinTLABSize = 2048 {product}
intx MonitorBound = 0 {product}
bool MonitorInUseLists = false {product}
intx MultiArrayExpandLimit = 6 {C2 product}
bool MustCallLoadClassInternal = false {product}
uintx NUMAChunkResizeWeight = 20 {product}
uintx NUMAInterleaveGranularity = 2097152 {product}
uintx NUMAPageScanRate = 256 {product}
uintx NUMASpaceResizeRate = 1073741824 {product}
bool NUMAStats = false {product}
ccstr NativeMemoryTracking = off {product}
bool NeedsDeoptSuspend = false {pd product}
bool NeverActAsServerClassMachine = false {pd product}
bool NeverTenure = false {product}
uintx NewRatio = 2 {product}
uintx NewSize := 10485760 {product}
uintx NewSizeThreadIncrease = 5320 {pd product}
intx NmethodSweepActivity = 10 {product}
intx NmethodSweepCheckInterval = 5 {product}
intx NmethodSweepFraction = 16 {product}
intx NodeLimitFudgeFactor = 2000 {C2 product}
uintx NumberOfGCLogFiles = 0 {product}
intx NumberOfLoopInstrToAlign = 4 {C2 product}
intx ObjectAlignmentInBytes = 8 {lp64_product}
uintx OldPLABSize = 1024 {product}
uintx OldPLABWeight = 50 {product}
uintx OldSize := 10485760 {product}
bool OmitStackTraceInFastThrow = true {product}
ccstrlist OnError = {product}
ccstrlist OnOutOfMemoryError = {product}
intx OnStackReplacePercentage = 140 {pd product}
bool OptimizeFill = true {C2 product}
bool OptimizePtrCompare = true {C2 product}
bool OptimizeStringConcat = true {C2 product}
bool OptoBundling = false {C2 pd product}
intx OptoLoopAlignment = 16 {pd product}
bool OptoScheduling = false {C2 pd product}
uintx PLABWeight = 75 {product}
bool PSChunkLargeArrays = true {product}
intx ParGCArrayScanChunk = 50 {product}
uintx ParGCDesiredObjsFromOverflowList = 20 {product}
bool ParGCTrimOverflow = true {product}
bool ParGCUseLocalOverflow = false {product}
uintx ParallelGCBufferWastePct = 10 {product}
uintx ParallelGCThreads = 8 {product}
bool ParallelGCVerbose = false {product}
uintx ParallelOldDeadWoodLimiterMean = 50 {product}
uintx ParallelOldDeadWoodLimiterStdDev = 80 {product}
bool ParallelRefProcBalancingEnabled = true {product}
bool ParallelRefProcEnabled = false {product}
bool PartialPeelAtUnsignedTests = true {C2 product}
bool PartialPeelLoop = true {C2 product}
intx PartialPeelNewPhiDelta = 0 {C2 product}
uintx PausePadding = 1 {product}
intx PerBytecodeRecompilationCutoff = 200 {product}
intx PerBytecodeTrapLimit = 4 {product}
intx PerMethodRecompilationCutoff = 400 {product}
intx PerMethodTrapLimit = 100 {product}
bool PerfAllowAtExitRegistration = false {product}
bool PerfBypassFileSystemCheck = false {product}
intx PerfDataMemorySize = 32768 {product}
intx PerfDataSamplingInterval = 50 {product}
ccstr PerfDataSaveFile = {product}
bool PerfDataSaveToFile = false {product}
bool PerfDisableSharedMem = false {product}
intx PerfMaxStringConstLength = 1024 {product}
intx PreInflateSpin = 10 {pd product}
bool PreferInterpreterNativeStubs = false {pd product}
intx PrefetchCopyIntervalInBytes = 576 {product}
intx PrefetchFieldsAhead = 1 {product}
intx PrefetchScanIntervalInBytes = 576 {product}
bool PreserveAllAnnotations = false {product}
bool PreserveFramePointer = false {pd product}
uintx PretenureSizeThreshold = 0 {product}
bool PrintAdaptiveSizePolicy = false {product}
bool PrintCMSInitiationStatistics = false {product}
intx PrintCMSStatistics = 0 {product}
bool PrintClassHistogram = false {manageable}
bool PrintClassHistogramAfterFullGC = false {manageable}
bool PrintClassHistogramBeforeFullGC = false {manageable}
bool PrintCodeCache = false {product}
bool PrintCodeCacheOnCompilation = false {product}
bool PrintCommandLineFlags = false {product}
bool PrintCompilation = false {product}
bool PrintConcurrentLocks = false {manageable}
intx PrintFLSCensus = 0 {product}
intx PrintFLSStatistics = 0 {product}
bool PrintFlagsFinal := true {product}
bool PrintFlagsInitial = false {product}
bool PrintGC := true {manageable}
bool PrintGCApplicationConcurrentTime = false {product}
bool PrintGCApplicationStoppedTime = false {product}
bool PrintGCCause = true {product}
bool PrintGCDateStamps := true {manageable}
bool PrintGCDetails := true {manageable}
bool PrintGCID = false {manageable}
bool PrintGCTaskTimeStamps = false {product}
bool PrintGCTimeStamps := true {manageable}
bool PrintHeapAtGC = false {product rw}
bool PrintHeapAtGCExtended = false {product rw}
bool PrintHeapAtSIGBREAK = true {product}
bool PrintJNIGCStalls = false {product}
bool PrintJNIResolving = false {product}
bool PrintOldPLAB = false {product}
bool PrintOopAddress = false {product}
bool PrintPLAB = false {product}
bool PrintParallelOldGCPhaseTimes = false {product}
bool PrintPromotionFailure = false {product}
bool PrintReferenceGC = false {product}
bool PrintSafepointStatistics = false {product}
intx PrintSafepointStatisticsCount = 300 {product}
intx PrintSafepointStatisticsTimeout = -1 {product}
bool PrintSharedArchiveAndExit = false {product}
bool PrintSharedDictionary = false {product}
bool PrintSharedSpaces = false {product}
bool PrintStringDeduplicationStatistics = false {product}
bool PrintStringTableStatistics = false {product}
bool PrintTLAB = false {product}
bool PrintTenuringDistribution = false {product}
bool PrintTieredEvents = false {product}
bool PrintVMOptions = false {product}
bool PrintVMQWaitTime = false {product}
bool PrintWarnings = true {product}
uintx ProcessDistributionStride = 4 {product}
bool ProfileInterpreter = true {pd product}
bool ProfileIntervals = false {product}
intx ProfileIntervalsTicks = 100 {product}
intx ProfileMaturityPercentage = 20 {product}
bool ProfileVM = false {product}
bool ProfilerPrintByteCodeStatistics = false {product}
bool ProfilerRecordPC = false {product}
uintx PromotedPadding = 3 {product}
uintx QueuedAllocationWarningCount = 0 {product}
uintx RTMRetryCount = 5 {ARCH product}
bool RangeCheckElimination = true {product}
intx ReadPrefetchInstr = 0 {ARCH product}
bool ReassociateInvariants = true {C2 product}
bool ReduceBulkZeroing = true {C2 product}
bool ReduceFieldZeroing = true {C2 product}
bool ReduceInitialCardMarks = true {C2 product}
bool ReduceSignalUsage = false {product}
intx RefDiscoveryPolicy = 0 {product}
bool ReflectionWrapResolutionErrors = true {product}
bool RegisterFinalizersAtInit = true {product}
bool RelaxAccessControlCheck = false {product}
ccstr ReplayDataFile = {product}
bool RequireSharedSpaces = false {product}
uintx ReservedCodeCacheSize = 251658240 {pd product}
bool ResizeOldPLAB = true {product}
bool ResizePLAB = true {product}
bool ResizeTLAB = true {pd product}
bool RestoreMXCSROnJNICalls = false {product}
bool RestrictContended = true {product}
bool RewriteBytecodes = true {pd product}
bool RewriteFrequentPairs = false {pd product}
intx SafepointPollOffset = 256 {C1 pd product}
intx SafepointSpinBeforeYield = 2000 {product}
bool SafepointTimeout = false {product}
intx SafepointTimeoutDelay = 10000 {product}
bool ScavengeBeforeFullGC = true {product}
intx SelfDestructTimer = 0 {product}
uintx SharedBaseAddress = 0 {product}
ccstr SharedClassListFile = {product}
uintx SharedMiscCodeSize = 122880 {product}
uintx SharedMiscDataSize = 4194304 {product}
uintx SharedReadOnlySize = 16777216 {product}
uintx SharedReadWriteSize = 16777216 {product}
uintx ShenandoahAllocationThreshold = 0 {product rw}
bool ShenandoahAlwaysPreTouch = false {product}
uintx ShenandoahFreeThreshold = 10 {product rw}
uintx ShenandoahFullGCThreshold = 3 {product rw}
ccstr ShenandoahGCHeuristics = adaptive {product}
uintx ShenandoahGarbageThreshold = 60 {product rw}
uintx ShenandoahHeapRegionSize = 0 {product}
bool ShenandoahLogDebug = false {product}
bool ShenandoahLogInfo = false {product}
bool ShenandoahLogTrace = false {product}
bool ShenandoahLogWarning = false {product}
bool ShenandoahOptimizeInstanceFinals = false {product}
bool ShenandoahOptimizeStableFinals = false {product}
bool ShenandoahOptimizeStaticFinals = true {product}
uintx ShenandoahRefProcFrequency = 5 {product}
bool ShenandoahRegionSampling = false {product rw}
int ShenandoahRegionSamplingRate = {product rw}
uintx ShenandoahUnloadClassesFrequency = 5 {product}
bool ShowMessageBoxOnError = false {product}
intx SoftRefLRUPolicyMSPerMB = 1000 {product}
bool SpecialEncodeISOArray = true {C2 product}
bool SplitIfBlocks = true {C2 product}
intx StackRedPages = 1 {pd product}
intx StackShadowPages = 6 {pd product}
bool StackTraceInThrowable = true {product}
intx StackYellowPages = 3 {pd product}
bool StartAttachListener = false {product}
intx StarvationMonitorInterval = 200 {product}
bool StressLdcRewrite = false {product}
uintx StringDeduplicationAgeThreshold = 3 {product}
uintx StringTableSize = 60013 {product}
bool SuppressFatalErrorMessage = false {product}
uintx SurvivorPadding = 3 {product}
uintx SurvivorRatio := 8 {product}
intx SuspendRetryCount = 50 {product}
intx SuspendRetryDelay = 5 {product}
intx SyncFlags = 0 {product}
ccstr SyncKnobs = {product}
intx SyncVerbose = 0 {product}
uintx TLABAllocationWeight = 35 {product}
uintx TLABRefillWasteFraction = 64 {product}
uintx TLABSize = 0 {product}
bool TLABStats = true {product}
uintx TLABWasteIncrement = 4 {product}
uintx TLABWasteTargetPercent = 1 {product}
uintx TargetPLABWastePct = 10 {product}
uintx TargetSurvivorRatio = 50 {product}
uintx TenuredGenerationSizeIncrement = 20 {product}
uintx TenuredGenerationSizeSupplement = 80 {product}
uintx TenuredGenerationSizeSupplementDecay = 2 {product}
intx ThreadPriorityPolicy = 0 {product}
bool ThreadPriorityVerbose = false {product}
uintx ThreadSafetyMargin = 52428800 {product}
intx ThreadStackSize = 0 {pd product}
uintx ThresholdTolerance = 10 {product}
intx Tier0BackedgeNotifyFreqLog = 10 {product}
intx Tier0InvokeNotifyFreqLog = 7 {product}
intx Tier0ProfilingStartPercentage = 200 {product}
intx Tier23InlineeNotifyFreqLog = 20 {product}
intx Tier2BackEdgeThreshold = 0 {product}
intx Tier2BackedgeNotifyFreqLog = 14 {product}
intx Tier2CompileThreshold = 0 {product}
intx Tier2InvokeNotifyFreqLog = 11 {product}
intx Tier3BackEdgeThreshold = 60000 {product}
intx Tier3BackedgeNotifyFreqLog = 13 {product}
intx Tier3CompileThreshold = 2000 {product}
intx Tier3DelayOff = 2 {product}
intx Tier3DelayOn = 5 {product}
intx Tier3InvocationThreshold = 200 {product}
intx Tier3InvokeNotifyFreqLog = 10 {product}
intx Tier3LoadFeedback = 5 {product}
intx Tier3MinInvocationThreshold = 100 {product}
intx Tier4BackEdgeThreshold = 40000 {product}
intx Tier4CompileThreshold = 15000 {product}
intx Tier4InvocationThreshold = 5000 {product}
intx Tier4LoadFeedback = 3 {product}
intx Tier4MinInvocationThreshold = 600 {product}
bool TieredCompilation = true {pd product}
intx TieredCompileTaskTimeout = 50 {product}
intx TieredRateUpdateMaxTime = 25 {product}
intx TieredRateUpdateMinTime = 1 {product}
intx TieredStopAtLevel = 4 {product}
bool TimeLinearScan = false {C1 product}
bool TraceBiasedLocking = false {product}
bool TraceClassLoading = false {product rw}
bool TraceClassLoadingPreorder = false {product}
bool TraceClassPaths = false {product}
bool TraceClassResolution = false {product}
bool TraceClassUnloading = false {product rw}
bool TraceDynamicGCThreads = false {product}
bool TraceGen0Time = false {product}
bool TraceGen1Time = false {product}
ccstr TraceJVMTI = {product}
bool TraceLoaderConstraints = false {product rw}
bool TraceMetadataHumongousAllocation = false {product}
bool TraceMonitorInflation = false {product}
bool TraceParallelOldGCTasks = false {product}
intx TraceRedefineClasses = 0 {product}
bool TraceSafepointCleanupTime = false {product}
bool TraceSuspendWaitFailures = false {product}
intx TrackedInitializationLimit = 50 {C2 product}
bool TransmitErrorReport = false {product}
bool TrapBasedNullChecks = false {pd product}
bool TrapBasedRangeChecks = false {C2 pd product}
intx TypeProfileArgsLimit = 2 {product}
uintx TypeProfileLevel = 111 {pd product}
intx TypeProfileMajorReceiverPercent = 90 {C2 product}
intx TypeProfileParmsLimit = 2 {product}
intx TypeProfileWidth = 2 {product}
intx UnguardOnExecutionViolation = 0 {product}
bool UnlinkSymbolsALot = false {product}
bool Use486InstrsOnly = false {ARCH product}
bool UseAES = true {product}
bool UseAESIntrinsics = true {product}
intx UseAVX = 2 {ARCH product}
bool UseAdaptiveGCBoundary = false {product}
bool UseAdaptiveGenerationSizePolicyAtMajorCollection = true {product}
bool UseAdaptiveGenerationSizePolicyAtMinorCollection = true {product}
bool UseAdaptiveNUMAChunkSizing = true {product}
bool UseAdaptiveSizeDecayMajorGCCost = true {product}
bool UseAdaptiveSizePolicy = true {product}
bool UseAdaptiveSizePolicyFootprintGoal = true {product}
bool UseAdaptiveSizePolicyWithSystemGC = false {product}
bool UseAddressNop = true {ARCH product}
bool UseAltSigs = false {product}
bool UseAutoGCSelectPolicy = false {product}
bool UseBMI1Instructions = true {ARCH product}
bool UseBMI2Instructions = true {ARCH product}
bool UseBiasedLocking = true {product}
bool UseBimorphicInlining = true {C2 product}
bool UseBoundThreads = true {product}
bool UseCLMUL = true {ARCH product}
bool UseCMSBestFit = true {product}
bool UseCMSCollectionPassing = true {product}
bool UseCMSCompactAtFullCollection = true {product}
bool UseCMSInitiatingOccupancyOnly = false {product}
bool UseCRC32Intrinsics = true {product}
bool UseCodeCacheFlushing = true {product}
bool UseCompiler = true {product}
bool UseCompilerSafepoints = true {product}
bool UseCompressedClassPointers := true {lp64_product}
bool UseCompressedOops := true {lp64_product}
bool UseConcMarkSweepGC = false {product}
bool UseCondCardMark = false {C2 product}
bool UseCountLeadingZerosInstruction = true {ARCH product}
bool UseCountTrailingZerosInstruction = true {ARCH product}
bool UseCountedLoopSafepoints = false {C2 product}
bool UseCounterDecay = true {product}
bool UseDivMod = true {C2 product}
bool UseDynamicNumberOfGCThreads = false {product}
bool UseFPUForSpilling = true {C2 product}
bool UseFastAccessorMethods = false {product}
bool UseFastEmptyMethods = false {product}
bool UseFastJNIAccessors = true {product}
bool UseFastStosb = true {ARCH product}
bool UseG1GC = false {product}
bool UseGCLogFileRotation = false {product}
bool UseGCOverheadLimit = true {product}
bool UseGCTaskAffinity = false {product}
bool UseHeavyMonitors = false {product}
bool UseInlineCaches = true {product}
bool UseInterpreter = true {product}
bool UseJumpTables = true {C2 product}
bool UseLWPSynchronization = true {product}
bool UseLargePages = false {pd product}
bool UseLargePagesInMetaspace = false {product}
bool UseLargePagesIndividualAllocation := false {pd product}
bool UseLockedTracing = false {product}
bool UseLoopCounter = true {product}
bool UseLoopInvariantCodeMotion = true {C1 product}
bool UseLoopPredicate = true {C2 product}
bool UseMathExactIntrinsics = true {C2 product}
bool UseMaximumCompactionOnSystemGC = true {product}
bool UseMembar = false {pd product}
bool UseMontgomeryMultiplyIntrinsic = true {C2 product}
bool UseMontgomerySquareIntrinsic = true {C2 product}
bool UseMulAddIntrinsic = true {C2 product}
bool UseMultiplyToLenIntrinsic = true {C2 product}
bool UseNUMA = false {product}
bool UseNUMAInterleaving = false {product}
bool UseNewLongLShift = false {ARCH product}
bool UseOSErrorReporting = false {pd product}
bool UseOldInlining = true {C2 product}
bool UseOnStackReplacement = true {pd product}
bool UseOnlyInlinedBimorphic = true {C2 product}
bool UseOptoBiasInlining = true {C2 product}
bool UsePSAdaptiveSurvivorSizePolicy = true {product}
bool UseParNewGC = false {product}
bool UseParallelGC := true {product}
bool UseParallelOldGC = true {product}
bool UsePerfData = true {product}
bool UsePopCountInstruction = true {product}
bool UseRDPCForConstantTableBase = false {C2 product}
bool UseRTMDeopt = false {ARCH product}
bool UseRTMLocking = false {ARCH product}
bool UseSHA = false {product}
bool UseSHA1Intrinsics = false {product}
bool UseSHA256Intrinsics = false {product}
bool UseSHA512Intrinsics = false {product}
intx UseSSE = 4 {product}
bool UseSSE42Intrinsics = true {product}
bool UseSerialGC = false {product}
bool UseSharedSpaces = false {product}
bool UseShenandoahGC = false {product}
bool UseSignalChaining = true {product}
bool UseSquareToLenIntrinsic = true {C2 product}
bool UseStoreImmI16 = false {ARCH product}
bool UseStringDeduplication = false {product}
bool UseSuperWord = true {C2 product}
bool UseTLAB = true {pd product}
bool UseThreadPriorities = true {pd product}
bool UseTypeProfile = true {product}
bool UseTypeSpeculation = true {C2 product}
bool UseUTCFileTimestamp = true {product}
bool UseUnalignedLoadStores = true {ARCH product}
bool UseVMInterruptibleIO = false {product}
bool UseXMMForArrayCopy = true {product}
bool UseXmmI2D = false {ARCH product}
bool UseXmmI2F = false {ARCH product}
bool UseXmmLoadAndClearUpper = true {ARCH product}
bool UseXmmRegToRegMoveAll = true {ARCH product}
bool VMThreadHintNoPreempt = false {product}
intx VMThreadPriority = -1 {product}
intx VMThreadStackSize = 0 {pd product}
intx ValueMapInitialSize = 11 {C1 product}
intx ValueMapMaxLoopSize = 8 {C1 product}
intx ValueSearchLimit = 1000 {C2 product}
bool VerifyMergedCPBytecodes = true {product}
bool VerifySharedSpaces = false {product}
intx WorkAroundNPTLTimedWaitHang = 1 {product}
uintx YoungGenerationSizeIncrement = 20 {product}
uintx YoungGenerationSizeSupplement = 80 {product}
uintx YoungGenerationSizeSupplementDecay = 8 {product}
uintx YoungPLABSize = 4096 {product}
bool ZeroTLAB = false {product}
intx hashCode = 5 {product}
Connected to the target VM, address: '127.0.0.1:55760', transport: 'socket'
2019-12-26T17:05:53.205+0800: 0.806: [GC (Allocation Failure) [PSYoungGen: 8192K->1016K(9216K)] 8192K->1553K(19456K), 0.0016892 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
2019-12-26T17:05:53.376+0800: 0.976: [GC (Allocation Failure) [PSYoungGen: 9208K->992K(9216K)] 9745K->2319K(19456K), 0.0014377 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
2019-12-26T17:05:53.539+0800: 1.140: [GC (Allocation Failure) [PSYoungGen: 9184K->1000K(9216K)] 10511K->3082K(19456K), 0.0019212 secs] [Times: user=0.08 sys=0.00, real=0.00 secs]
2019-12-26T17:05:53.593+0800: 1.193: [GC (Allocation Failure) --[PSYoungGen: 8826K->8826K(9216K)] 16028K->16318K(19456K), 0.0020696 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
2019-12-26T17:05:53.595+0800: 1.196: [Full GC (Ergonomics) [PSYoungGen: 8826K->6137K(9216K)] [ParOldGen: 7491K->6470K(10240K)] 16318K->12607K(19456K), [Metaspace: 8221K->8221K(1056768K)], 0.0183229 secs] [Times: user=0.11 sys=0.00, real=0.02 secs]
9)PrintAdaptiveSizePolicy
打印 G1 GC 自适应策略的变化过程,包括:
- 年轻代大小(Eden + Survivor)如何动态调整
- 目标暂停时间是否达标
- 各区域分配策略变化
(G1Ergonomics) (Core) resize young gen to 4026531840 bytes
(G1Ergonomics) (Mixed GCs) do not start mixed GCs, still doing collection sets
(G1EvacStats) average live bytes per region: 1.2M
性能影响:非常低,性能影响 < 0.5%,短期开启无压力,长期运行需评估磁盘 IO
- 属于调试日志级别,输出较频繁
- 主要在 GC pause 中触发,不影响业务线程执行
- 每次 GC 输出几行文本,总体开销仍很小
| 场景 | 是否推荐启用 |
|---|---|
| 调优 G1 新生代大小(G1NewSizePercent / G1MaxNewSizePercent) | ✔️ 推荐 |
| 排查“年轻代忽大忽小”导致 GC 不稳定 | ✔️ 推荐 |
| 分析为何 G1 没有按预期扩大 Eden 区 | ✔️ 推荐 |
| 生产环境常规运行 | ❌ 不建议长期开启 |
| 高并发服务(QPS > 5000) | ⚠️ 仅限短时间诊断 |
2、路径
1)-Xloggc
-Xloggc用于指定垃圾回收日志文件的路径,主要用于分析和优化垃圾回收行为。
-Xloggc参数用于指定垃圾回收(GarbageCollection,GC)日志文件的路径。垃圾回收是JVM自动回收不再使用的内存空间的过程,通过检测不再需要的对象并释放它们占用的内存,以提高应用程序的性能和效率。配置
-Xloggc参数可以将垃圾回收日志记录到指定的文件中,以便更详细地了解垃圾回收的发生和影响。这对于分析和优化垃圾回收行为、确定是否存在内存泄漏或内存不足的问题非常有帮助。例如:
-Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8
-verbose:gc
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+PrintGCTimeStamps
-Xloggc:D:\programFiles\java-1.8.0-openjdk\log\gc.log
2)-Djava.library.path=/usr/local/lib
这个参数用于设置
Java虚拟机(JVM)在加载本地库(nativelibraries)时搜索的路径。java.library.path是一个系统属性,它告诉JVM在哪里查找通过System.loadLibrary()方法加载的本地库。在这个例子中,路径被设置为/usr/local/lib,这意味着JVM会在这个目录下搜索本地库文件(如.so、.dll或.dylib文件,具体取决于操作系统)。 如果你的应用程序依赖于特定的本地库,并且这些库不在JVM默认的搜索路径中,你就需要使用这个参数来指定正确的路径。
3)-XX:HeapDumpPath
-XX:HeapDumpPath用于指定堆转储文件的路径,主要用于诊断内存相关问题。
-XX:HeapDumpPath参数用于指定生成堆转储文件(HeapDump)的路径。堆转储文件是JVM堆内存的快照,包含了在生成快照时堆中的所有对象和类的信息。这些信息对于诊断内存泄漏、垃圾回收问题和java.lang.OutOfMemoryError等内存相关问题至关重要。当
JVM出现内存溢出错误或其他内存相关问题时,可以配置-XX:+HeapDumpOnOutOfMemoryError参数来启用在内存溢出时自动生成堆转储文件的功能,并通过-XX:HeapDumpPath参数来指定堆转储文件的保存路径。例如:
3、启动模式
hotspot包括server和client两种模式的实现:⬤
JavaHotSpotClientVM(-client),为在客户端环境中减少启动时间而优化;⬤
JavaHotSpotServerVM(-server),为在服务器环境中最大化程序执行速度而设计。
1)比较
因为
Server模式启动的JVM采用的是重量级的虚拟机,对程序采用了更多的优化,server模式会尝试收集更多的系统性能信息,使用更复杂的优化算法对程序进行优化。而Client模式启动的JVM采用的是轻量级的虚拟机两种模式的区别在于,
Client模式启动速度较快,Server模式启动较慢;但是启动进入稳定期长期运行之后Server模式的程序运行速度比Client要快很多。因此当系统完全启动并进入运行稳定期后,
server模式的执行速度会远远快于client模式,所以在对于后台长期运行的系统,使用server模式启动对系统的整体性能可以有不小的帮助,但对于用户界面程序,运行时间不长,又追求启动速度建议使用client模式启动
2)模式查看
看了一下
hotspot的安装的模式,32位的hotspot都是client模式;64位的都是server模式的。
└─[$] java -version [17:04:
java version "1.8.0_271"
Java(TM) SE Runtime Environment (build 1.8.0_271-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.271-b09, mixed mode)
┌─[healerjean@HealerJn2023MAC] - [~] - [2734]
└─[$]
3) Client 与 Server 切换
首先要确认
JDK支持哪一种或两种模式。查看JAVA_HOME/jre/bin目录下是否存在client或server目录。32位的JDK一般都支持server和client两种模式。64位的虚拟机好像只支持server模式(不能修改模式),没有client目录。如下为32位JDK模式支持目录:
4、开启一个远程支持访问的
| 参数 | 类型 | 描述 |
|---|---|---|
| -Dcom.sun.management.jmxremote | 布尔 | 默认为true |
| -Dcom.sun.management.jmxremote.port | 数字 | 监听端口号,方便远程访问 |
| -Dcom.sun.management.jmxremote.authenticate | 布尔 | 是否需要开启用户认证,默认开启,指定了JMX 是否启用鉴权(需要用户名,密码鉴权) |
| -Dcom.sun.management.jmxremote.ssl | 布尔 | 是否对连接开启SSL加密,默认开启 |
| -Dcom.sun.management.jmxremote.access.file | 路径 | 配置用户权限文件路径,默认路径JRE_HOME/lib/management/jmxremote.access |
| -Dcom.sun.management.jmxremote. password.file | 路径 | 用户名和密码,默认路径JRE_HOME/lib/management/ jmxremote.password |
1)启动 JVM 监控,不配置用户名和密码
一般情况下,不用配置用户名和密码,防火墙可以指定某些ip才能访问
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=10200
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

2)配置用户名和密码(一般没必要)
1、密码配置 :将以下信息保存到相应的文件里面,比如jmxremote.password,具体设置可参考 ${JAVA_HOME}/jre/lib/management/jmxremote.password.template。
healerjean 123456
monitorRole 123456
controlRole 123456
2、用户权限分配 :将上面的信息保存到相应的文件里面,比如jmxremote.access。关于用户和权限的配置可以参见${JAVA_HOME}/jre/lib/management/jmxremote.access文件
healerjean readwrite
monitorRole readonly
controlRole readwrite
3、参数配置
1、Linux权限配置
chmod 600 jmxremote.access
chmod 600 jmxremote.password
windos权限配置
右键单击文件 jmxremote.password,弹出菜单中选“属性”,再点“安全”/“高级”/“更改权限”/“包括可从该对象的父项继承的权限”(弹出窗口中选“删除”以删除所有访问权限);
再选“添加”/“高级”/“立即查找”,选中你的用户(如HealerJean),点“确定”; 权限项目窗口中勾选“完全控制”,点“确定”。
4、配置参数访问
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=10200
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=true
-Dcom.sun.management.jmxremote.password.file=D:\programFiles\java-1.8.0-openjdk\jre\lib\management\auth\jmxremote.password
-Dcom.sun.management.jmxremote.access.file=D:\programFiles\java-1.8.0-openjdk\jre\lib\management\auth\jmxremote.access
三、JVM 参数
| 检测指标 | 建议 |
|---|---|
JVM 版本 |
版本不低于1.8.0_191 |
JVM GC 方法 |
所有分组GC方法一致 |
Xmx |
明确指定,并且在容器内存的50%~80%范围内 |
Xms |
明确指定,并且等于Xmx指定的值 |
-XX:MaxDirectMemorySize |
明确指定,并且 堆内 * 1.1+ 堆外+系统预留 <= 容器内存 |
ParallelGCThreads |
ParallelGCThreads 在容器CPU核数的 50%~100%范围内 |
ConcGCThreads |
ConcGCThreads 在 ParallelGCThreads 的 20% ~ 50 %范围内(限 CMS,G1) |
CICompilerCount |
指定 CICompilerCount在推荐值 50% ~150% 内(限 1.8 < JRE < 1.8.0_131) |
1、堆区
| 参数 | 说明 | 默认值 | 用法 |
|---|---|---|---|
-Xms |
堆区内存初始内存分配的大小 | 默认值为容器内存的 1/64, 最小8MB,如果明确指定了 Xmx并 且小于容器内存1/64, Xms 默认值为Xmx指定的值。 |
通常为默认即可,但有可能真的按照这样的一个规则分配时,设计出的软件还没有能够运行得起来就挂了。所以仍需按照实际情况进行分配。 |
-Xmx |
堆区内存可被分配的最大上限 | Xmx 的默认值比较复杂,官方文档上有时候写的是1GB,但实际值跟JRE 版本、JVM 模式( client, server)和系统(平台类型,32 位,64 位)等都有关。经过查阅源码和实验,确定在生产环境下(server模式,64位Centos,JRE 8),Xmx的默认值可以采用以下规则计算:⬤ 容器内存小于等于2G:默认值为容器内存的1/2,最小16MB, 最大512MB。 ⬤ 容器内存大于2G:默认值为容器内存的1/4, 最大可到达32G。 |
⬤ 通常会将 -Xms 与 -Xmx两个参数的配置相同的值,其目的是为了能够在java垃圾回收机制清理完堆区后不需要重新分隔计算堆区的大小而浪费资源。⬤ 推荐设置为容器内存的50%,不能超过容器内存的80% |
-XX:newSize |
新生代初始内存的大小 | 应该小于 -Xms的值; |
|
-XX:MaxnewSize |
新生代可被分配的内存的最大上限 | 应该小于 -Xmx的值; |
|
-Xmn |
年轻代大小 | 这个参数则是对 -XX:newSize、-XX:MaxnewSize两个参数的同时配置 ,-XX:newSize = -XX:MaxnewSize = -Xmn((Sun官方建议年轻代的大小为整个堆的3/8左右)) |
|
-XX:SurvivorRatio |
年轻代中Eden区与Survivor区的大小比值 | 一般设置为8 | 设置年轻代中Eden区与Survivor区的大小比值。-XX:SurvivorRatio=8,则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10 |
-XX:NewRatio |
设置年轻代与年老代的比值 | 默认 2,即年轻代和年老代的比例为1:2, 年轻代大小为堆内内存的1/3。 |
-XX:NewRatio = 4 :。设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5,一般不使用 |
2、栈区(每个线程的大小 )
操作系统分配给每个进程的内存是有限制的,虚拟机提供了参数来控制非堆区(MaxPermSize)和 Java 堆(Xmx)区这两部分的最大值
操作系统剩余的内存减去Xmx(最大堆区容量)和MaxPermSize(最大方法区容量),,程序计数器内存消耗很小可以忽略掉,如果虚拟机进程本身消耗的内存不计算在内,剩下的就给了虚拟机栈和本地方法栈了。
每个线程分配到的栈容量越大,可以建立的线程数就越少,建立线程时就越容易将资源耗尽。
栈深度在大多数情况下达到1000到2000没有问题,对于正常的方法调用(包括递归),这个深度完全够用了,但是如果是建立多线程导致的内存溢出,在不能减少线程数,或者更换虚拟机的情况下,就只能通过减少最大堆(这样可以让栈区多一些)、减少线程分配的栈容量(如果当前线程占用的栈资源允许的情况下)
| 参数 | 说明 | 默认值 | 用法 |
|---|---|---|---|
-Xss |
设置每个线程的栈大小 | 1M | JDK5.0 以后每个线程栈大小为1M,以前每个线程栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。 |
3、持久代
持久代(非堆区,方法区)一般固定大小为64m
| 参数 | 说明 | 默认值 | 用法 |
|---|---|---|---|
-XX:PermSize |
非堆区初始化内存大小 | ||
-XX:MaxPermSize |
非堆区最大的内存大小 |
4、最大直接内存
a、什么是直接内存
Direct Byte Buffers 是通过JNI 调用操作系统原生接口分配的堆外内存,不属于 JVM 堆内存范畴,是狭义上 “堆外内存” 的核心形态。其核心特征:
- 内存分配 / 释放依赖
Unsafe.allocateMemory()/Unsafe.freeMemory()原生方法; - 内存地址连续、固定,不受
JVM GC内存移动影响; DirectByteBuffer对象仅作为堆外内存的 “引用壳”,存储内存地址和大小,本身占用堆内存极小。
b、为什么要使用直接内存
核心价值是提升 I/O 效率、降低 GC 压力,尤其适配高性能场景:
为了了更高效的进行 Socket I/O 或文件读写等内核态资源操作,会使用 JNI( Java 原生接口),此时操作的内存需要是连续和确定的。而 Heap 中的内存不能保证连续,且 GC 也可能导致对象随时移动。
- 因此涉及
Output操作时,不直接使用Heap上的数据,需要先从Heap上拷贝到原生内存 Input操作则相反。因此为了避免多余的拷贝,提高I/O效率,不少第三方包和框架使用Direct Byte Buffers,比Netty。
| 场景 | 堆内存 I/O 问题 |
直接内存解决方案 |
|---|---|---|
网络编程(RPC) |
数据需从堆内存拷贝到内核缓冲区(两次拷贝),GC 停顿影响低延迟 |
数据直接读写内核缓冲区(零拷贝),绕过堆内存拷贝,降低 GC 对 I/O 的影响 |
文件 I/O |
堆内存缓存大文件易触发频繁 GC,内存碎片多 |
直接内存存储文件数据,避免堆内存拷贝,减少 GC 频率 |
| 低延迟系统 | GC 停顿导致业务延迟超标 |
用直接内存存储临时数据,规避堆内存 GC 停顿 |
| 大数据处理 | 堆内存不足导致 OOM,频繁 Full GC |
分配大块直接内存存储数据,提升数据处理吞吐量 |
问题1:为什么要使用堆外内存?
DirectByteBuffer 在创建的时候会通过 Unsafe 的 native 方法来直接使用 malloc 分配一块内存,这块内存是 heap 之外的,那么自然也不会对 gc 造成什么影响( System.gc 除外),因为 gc 耗时的操作主要是操作 heap 之内的对象,对这块内存的操作也是直接通过 Unsafe 的 native 方法来操作的,相当于 DirectByteBuffer 仅仅是一个壳,还有我们通信过程中如果数据是在 Heap 里的,最终也还是会 copy 一份到堆外,然后再进行发送,所以为什么不直接使用堆外内存呢。对于需要频繁操作的内存,并且仅仅是临时存在一会的,都建议使用堆外内存,并且做成缓冲池,不断循环利用这块内存。
问题2:为什么不能大面积使用堆外内存
如果我们大面积使用堆外内存并且没有限制,那迟早会导致内存溢出,毕竟程序是跑在一台资源受限的机器上,因为这块内存的回收不是你直接能控制的,当然你可以通过别的一些途径,比如反射,直接使用 Unsafe 接口等,但是这些务必给你带来了一些烦恼,Java 与生俱来的优势被你完全抛弃了—开发不需要关注内存的回收,由 gc 算法自动去实现。另外上面的 gc 机制与堆外内存的关系也说了,如果一直触发不了 cms gc 或者 full gc,那么后果可能很严重。
| 场景 | 堆内存问题 | 堆外内存解决方案 |
|---|---|---|
| 高频交易系统 | GC停顿导致延迟敏感 | 使用DirectByteBuffer绕过GC |
| 大数据处理 | 堆内存不足,频繁GC | 分配大块堆外内存,减少拷贝开销 |
| 内存敏感型应用 | 堆内存碎片化,OOM风险 | 手动管理内存生命周期,共享数据 |
c、直接内存的风险与回收机制
核心风险
- 回收被动性:直接内存释放依赖
DirectByteBuffer对象被GC标记为不可达,若对象泄漏(如未关闭的连接持有引用),会导致堆外内存持续占用; - 溢出风险:若直接内存使用量超过
-XX:MaxDirectMemorySize,或未设置该参数导致占用系统内存过高,会触发OutOfMemoryError: Direct buffer memory,甚至进程被系统OOM Killer杀死; - 管理复杂度:手动分配直接内存需关注生命周期,违背
Java“自动内存管理” 的设计初衷,易引发内存泄漏。
回收机制
- 常规回收:当
DirectByteBuffer被GC(如Young GC/Full GC/ZGC并发回收)标记为不可达时,JVM会通过Cleaner机制调用Unsafe.freeMemory()释放对应的直接内存; ZGC/JDK 21优化:ZGC支持并发扫描并回收DirectByteBuffer,无需等待Full GC,回收效率远高于传统GC。
d、关键配置参数说明
| 配置规则 | 风险提示 |
|---|---|
默认值:未显式指定时为 Runtime.getRuntime().maxMemory()(略小于 -Xmx,即堆内存最大值减去一个 Survivor 区) |
默认值过大易导致堆外内存泄漏,耗尽系统内存;过小则触发直接内存溢出 |
| 显式指定:建议在启动参数中明确配置,避免依赖默认值 | 需结合业务 I/O 强度、机器内存规格合理设置,不可盲目调大 / 调小 |
e、内存总量计算公式(容器 / 物理机通用)
- 容器内存 ≥
Xmx+MaxMetaspace+ (maxThreads×Xss) +DirectMem+512MB(系统预留内存)
| 参数 | 说明 | 推荐设置 | 示例 |
|---|---|---|---|
Xmx |
Java 堆最大值 | 根据应用对象大小设置 | -Xmx2g |
MaxMetaspaceSize |
元空间上限 | 一般 128m ~ 512m | -XX:MaxMetaspaceSize=256m |
maxThreads |
最大线程数(如 Tomcat) | 尽量控制在 200~500 | maxThreads="500" |
Xss |
每个线程栈大小 | 强烈建议调小 | -Xss256k(默认 1m 太大) |
MaxDirectMemorySize |
直接内存上限 | 通常 128m ~ 512m | -XX:MaxDirectMemorySize=256m |
ReservedCodeCacheSize |
JIT 代码缓存 | 默认 ~240m | -XX:ReservedCodeCacheSize=256m |
OffHeapOverhead |
其他堆外开销 | 建议预留 256~512MB | + 512m |
VM 总内存 ≈
Xmx + // Java 堆最大值
MaxMetaspaceSize + // 类元数据空间
(maxThreads × Xss) + // 所有线程栈总和
MaxDirectMemorySize + // 直接内存(如 NIO)
ReservedCodeCacheSize + // JIT 编译代码缓存
OffHeapOverhead // 其他开销(GC、线程本地缓存等)
f、分场景配置建议
- 常规应用(无高频 I/O)
- 特征:少量
NIO操作,无大规模网络 / 文件I/O; - 配置:
-XX:MaxDirectMemorySize=256M,沿用默认值或小幅调整; - 核心:避免直接内存占用过多系统资源。
- I/O 密集应用(RPC/Netty/ 大文件处理)
- 特征:高频网络
I/O(如 Dubbo/gRPC)、大文件读写,依赖Netty等 NIO 框架; - 配置:8C16G 机器建议
2G,16C32G机器建议3G~4G; - 配套优化:
- 开启
Netty直接内存池化(io.netty.allocator.type=pooled) - 复用
DirectByteBuffer,减少内存碎片和创建开销。
- 开启
- 低延迟 / 高频交易系统
- 特征:对
GC停顿敏感,需极致 I/O 性能; - 配置:
-XX:MaxDirectMemorySize=4G~8G(按机器内存调整),结合 ZGC 降低回收延迟; - 配套优化:禁用
-XX:+DisableExplicitGC(避免影响直接内存回收),监控直接内存使用率。
g、监控与调优
- 调优原则
- 使用率稳定在 50%~70%:配置合理;
- 频繁接近上限(>90%):逐步调高
MaxDirectMemorySize,或排查内存泄漏; - 长期低使用率(<30%):适当调低,节省系统内存。
5、元空间
Metaspace(元空间)是JDK8关于方法区新的实现,取代之前的永久代,用来保存类、方法、数据结构等运行时信息和元信息的。很多研发在老版本时可能遇到过java.lang.OutOfMemoryError: PermGen Space,这说明永久代的空间不够用了,JDK7以前可以通过-XX:PermSize,-XX:MaxPermSize来指定永久代的初始大小和最大大小。JDK8中Metaspace取代永久代,位置由JVM内存变成系统原生内存,也取消默认的最大空间限制。与此有关的参数主要有下面两个:
| 参数 | 说明 | 默认值 | 用法 |
|---|---|---|---|
-XX:MaxMetaspaceSize |
指定元空间的最大空间 | 默认为容器剩余的所有空间 | |
-XX:MetaspaceSize |
指定元空间首次扩充的大小 | 默认为20.8M |
⬤ 由于 MaxMetaspaceSize 未指定时,默认无上限,所以需要特别关注内存泄露的问题,如果程序动态的创建了很多类,或出现过java.lang.OutOfMemoryError:Metaspace,建议明确指定 -XX:MaxMetaspaceSize。另外 Metaspace 实际分配的大小是随着需要逐步扩大的,每次扩大需要一次 FGC,-XX:MetaspaceSize 默认的值比较小,需要频繁 GC 扩充到需要的大小。通过下面的日志可以看到Metaspace 引起的 FGC:
⬤ 为减少预热影响,可以将 -XX:MetaspaceSize,-XX:MaxMetaspaceSize 指定成相同的值。另外不少应用由 JDK7 升级到了 JDK8,但是启动参数中仍有 -XX:PermSize,-XX:MaxPermSize,这些参数是不生效的,建议修改成 -XX:MetaspaceSize,-XX:MaxMetaspaceSize。
6、垃圾收集器选择

| 参数 | 收集器名称 | 收集算法 | 方式 | 收集对象 | 用法 |
|---|---|---|---|---|---|
-XX:+UseSerialGC |
Serial | 复制 | 串行 | 新生代 | 虚拟机运行在Client模式的默认值,打开此开关参数后,使用Serial+Serial Old收集器组合进行垃圾收集。 |
-XX:+UseParNewGC |
ParNew | 复制 | 并行 | 新生代 | 开启此参数使用ParNew & serial old搜集器 |
-XX:+UseParallelG |
parallel Scavenge | 复制 | 并行 | 新生代 | 开启此参数使用·parallel scavenge & parallel old搜集器(server模式默认值) |
| serial old | 标记-整理 | 串行 | 老年代 | ||
-XX:+UseParalledlOldGC |
Parallel Old | 标记-整理 | 并行 | 老年代 | 打开此开关参数后,使用Parallel Scavenge+Parallel Old收集器组合进行垃圾收集。 |
-XX:+UseConcMarkSweepGC |
CMS | 标记-清除 | 并发 | 老年代 | 打开此开关参数后,使用ParNew+CMS+Serial Old收集器组合进行垃圾收集。Serial Old作为CMS收集器出现Concurrent Mode Failure的备用垃圾收集器。 |
1)老年代-参数
| 参数 | 说明 | 默认值 | 用法 |
|---|---|---|---|
XX:MaxTenuringThreshold |
垃圾最大年龄 | 15 | 如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。 如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概率 |
-XX:PretenureSizeThreshold |
晋升年老代的对象大小 | 0:不管多大都是先在eden中分配内存 | 如设为10M,则超过10M的对象将不在eden区分配,而直接进入年老代。 |
2)并行收集器参数
| 参数 | 说明 | 默认值 | 用法 |
|---|---|---|---|
-XX:ParallelGCThreads |
指定垃圾收集的线程数量 | 默认与CPU个数相等 |
ParallelGCThreads在容器 CPU核数的50%~100%范围内 |
-XX:GCTimeRatio |
置垃圾收集时间占总时间的比率 | 设置系统的吞吐量。比如设为99,则GC时间比为1/1+99=1%,也就是要求吞吐量为99%。垃圾收集所花费的时间是年轻一代和老年代收集的总时间;如果没有满足吞吐量目标,则增加新生代的内存大小以尽量增加用户程序运行的时间; | |
-XX:MaxGCPauseMillis |
设置垃圾回收的最长时间 | 若无法满足设置值,则会优先缩小新生代大小,仍无法满足的话则会牺牲吞吐量。 | |
CICompilerCount |
是 JIT 进行热点编译的线程数,和并发标记线程数一样,热点编译也是 CPU 密集型任务, |
默认值为2,该参数的值会根据服务器的 CPU 数量进行调整 |
``CICompilerCount 是 JIT 进行热点编译的线程数,和并发标记线程数一样,热点编译也是 CPU 密集型任务,默认值为2。在 CICompilerCountPerCPU 开启的时候( JDK7 默认关闭,JDK8 默认开启),手动指定 CICompilerCount 是不会生效的,JVM 会使用系统 CPU 核数进行计算。所以当使用 JDK8 并且版本小于1.8.0_131,采用默认参数时,CICompilerCount会在20 左右,对业务性能影响较大,特别是启动阶段。建议升级Java版本,特殊情况要使用老版本 Java 8,请加上-XX:CICompilerCount=[n ], 同时不能指定-XX:+CICompilerCountPerCPU ,下表给出了生产环境下常见规格的推荐值。 |
a、CICompilerCount

| 容器核数 | 1 | 2 | 4 | 8 | 16 |
|---|---|---|---|---|---|
CICompilerCount 手动指定推荐值 |
2 | 2 | 3 | 3 | 8 |
1、不同 JVM 版本的默认值
CICompilerCount 的默认值取决于 JVM 版本、运行模式(Client/Server)和 CPU 核心数:
| JVM 版本 | 默认值计算逻辑 | 控制 | 示例(8 核 CPU) |
|---|---|---|---|
Java 8 及以前 |
- 客户端模式(Client VM):CICompilerCount = 2 - 服务器模式( Server VM):CICompilerCount = 2 + min(3, 核心数/4) |
仅控制 C2 编译器线程数 | Server 模式:2 + min(3, 8/4) = 4 |
Java 9+ |
- 统一使用 -XX:ParallelCompilerThreads 参数 - 默认值:min(8, 核心数), |
统一控制所有编译器线程数 | min(8, 8) = 8 |
Java 17+ |
- 动态调整策略更激进,默认值仍为 min(8, 核心数),但支持自适应编译线程数(-XX:+AdaptiveSizePolicy) |
8 |
| 场景 | CPU 核心数 | CICompilerCount 建议值 | 原因 |
|---|---|---|---|
| 小型应用程序或开发测试环境,对启动速度要求较高,编译任务相对较少 | 1 - 2 核 | 2 | 对于单核或双核环境,默认值 2 通常是比较合适的,能在一定程度上平衡编译速度和系统资源占用。此时应用程序编译任务量不大,过多线程可能会带来线程切换开销,反而影响性能1。 |
| 中型企业级应用,并发量中等,有一定编译需求 | 4 核 | 2 - 4 | 4 核 CPU 有一定计算能力,设置为 2 能保证基本编译效率,若应用编译任务较多,可适当增加到 4,充分利用 CPU 资源,加快编译速度,提升应用性能。 |
| 大型企业级应用,高并发场景,编译任务繁重 | 8 核及以上 | 4 - 8 | 8 核及以上 CPU 资源丰富,大型高并发应用有大量代码需编译优化,较多编译线程可并行处理编译任务,减少编译时间,使应用更快达到最佳性能状态。如电商促销活动期间的后台系统,高并发请求下需要快速编译相关代码以保证服务响应速度。 |
| 深度学习等计算密集型场景 | 多核心(如 16 核、32 核等) | 6 或更高,可根据实际核数适当增加 | 深度学习训练过程中会有大量代码编译及计算任务,需要充分利用多核 CPU 性能。将 CICompilerCount 设置为 6 或更高,能让 JIT 编译器更高效地编译相关代码,为模型训练提供更好的性能支持,加速训练过程2。 |
| 容器环境,资源受限且需精准控制 | 根据容器分配核数而定 | 一般可设置为与容器核数相同或略少(如核数的 75% 左右) | 容器环境下资源受 CGroup 限制,JVM 可能无法正确识别真实 CPU 资源情况5。设置为与容器核数相同或略少,可确保编译线程不占用过多资源,避免影响其他容器内应用或导致系统资源竞争,保证应用稳定运行。例如在微服务架构中,每个容器承载一个微服务,可按此原则根据容器核数配置编译线程数6。 |
3)并发收集器参数
| 参数 | 说明 | 默认值 | 用法 |
|---|---|---|---|
-XX:CMSInitiatingOccupancyFraction |
设置CMS预留内存空间 | 触发CMS收集器的内存比例。比如60%的意思就是说,当内存达到60%,就会开始进行CMS并发收集。 | |
-XX:UseCMSCompactAtFullCollection |
是否在每一次CMS收集器清理垃圾后送一次内存整理。 | true | 目前默认就是true了,默认每次GC直接压缩 |
-XX:UseCMSCompactAtFullCollection |
上一次CMS并发GC执行过后,到底还要再执行多少次full GC才会做压缩,从而触发一次内存整理 | ||
ConcGCThreads |
并发标记线程数 | ⬤ CMS默认ParallelGCThreads+3 / 4⬤ G1下是 ParallelGCThreads / 4 四舍五入 |
⬤ ConcGCThreads 在 ParallelGCThreads 的20%~50%范围内(限 CMS,G1)⬤ ConcGCThreads 一般称为并发标记线程数,为了减少 GC 的 STW的时间,CMS 和 G1 都有并发标记的过程,此时业务线程仍在工作,只是并发标记是 CPU 密集型任务,业务的吞吐量会下降,RT 会变长。ConcGCThreads 的默认值不同GC 策略略有不同,CMS 下是 ( ParallelGCThreads + 3) / 4 向下取整,G1下是 ParallelGCThreads / 4 四舍五入。一般来说采用默认值就可以了,但是还是由于在 JRE 版本 1.8.0_131之前,JVM无法感知 Docker 的资源限制的问题,ConcGCThreads 的默认值会比较大(20 左右),对业务会有影响。 |
二、JVM 工具使用
| 名称 | 全称 | 主要作用 |
|---|---|---|
jps |
jvm process status tool |
显示指定系统内所有的hotspot虚拟机进程 |
jstat |
jvm statistics monitoring tool |
用于收集hotspot虚拟机各方面的运行数据 |
jinfo |
configuration info for java |
实时查看和调整虚拟机的各项参数 |
jmap |
memory map for java |
生成虚拟机的内存转储快照(heapdump文件) |
jhat |
jvm heap dump browser |
用于分析heapmap文件,它会建立一个http/html服务器让用户可以在浏览器上查看分析结果 |
jstack |
stack trace for java |
显示虚拟机的线程快照,定位死循环,线程阻塞,死锁等问题 |
1、jps
jvm process status虚拟机进程状态
| 命令 | 说明 |
|---|---|
jps - l |
进程号、输出主类或者jar的完全路径名、 |
jps -v |
输出jvm参数 |
jps -q |
只显示进程号 |
1)jps -l
进程号、输出主类或者jar的完全路径名
package com.hlj.moudle.Jvm04_Command;
import java.util.Scanner;
public class Jvm04_01jps {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
sc.nextLine();
}
}
$ jps -l
14992 com.caucho.server.resin.Resin
16864 org.jetbrains.jps.cmdline.Launcher
15892 org.jetbrains.idea.maven.server.RemoteMavenServer
6916 org.jetbrains.jps.cmdline.Launcher
6980 sun.tools.jps.Jps
13688 org.jetbrains.kotlin.daemon.KotlinCompileDaemon
14684 com.hlj.moudle.Jvm04_Command.Jvm04_01jps
5948
$ jps -l | grep Jvm
14684 com.hlj.moudle.Jvm04_Command.Jvm04_01jps
2)jps –v
输出jvm参数(查看已经运行的main的JVM参数)
-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8
package com.hlj.moudle.Jvm04_Command;
import java.util.Scanner;
public class Jvm04_01jps {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
sc.nextLine();
}
}
$ jps -v | grep Jvm04
18228 Jvm04_01jps -Dvisualvm.id=15978156520281 -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -javaagent:D:\programFiles\IntelliJ IDEA 2018.3.5\lib\idea_rt.jar=52554:D:\programFiles\IntelliJ IDEA 2018.3.5\bin -Dfile.encoding=UTF-8
1、使用Linux命令查看进程以及参数配置
ps -aux |grep scf-ma
[work@vm10-123-3-2 bin]$ ps -aux |grep scf-ma
work 12566 0.5 4.5 11541924 1483512 ? Sl Jan02 37:54 /usr/local/service/app/scf/scf-manager/jdk1.8.0_202/bin/java -Xmn256M -Xmx1024M -Xms1024M -XX:MaxPermSize=256M -XX:PermSize=256M -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC -XX:CMSFullGCsBeforeCompaction=50 -XX:+UseCMSCompactAtFullCollection -XX:MaxTenuringThreshold=10 -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintFlagsFinal -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8393 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Xloggc:/usr/local/service/log/scf/scf-manager/gc.log -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=19137 -Dlog4j2.isThreadContextMapInheritable=true -Djava.util.logging.manager=com.caucho.log.LogManagerImpl -Djava.system.class.loader=com.caucho.loader.SystemClassLoader -Djava.endorsed.dirs=/usr/local/service/app/scf/scf-manager/jdk1.8.0_202/jre/lib/endorsed:/usr/local/service/app/scf/scf-manager/resin-pro-4.0.58/endorsed -Djavax.management.builder.initial=com.caucho.jmx.MBeanServerBuilderImpl -Djava.awt.headless=true -Dresin.home=/usr/local/service/app/scf/scf-manager/resin-pro-4.0.58 -server com.caucho.server.resin.Resin --root-directory /usr/local/service/app/scf/scf-manager/resin-pro-4.0.58 -conf ./../conf/resin.xml -server scf-manager start
3)jps -q
值显示
java进程号,什么都看不出来
package com.hlj.moudle.Jvm04_Command;
import java.util.Scanner;
public class Jvm04_01jps {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
sc.nextLine();
}
}
$ jps -q
14992
15892
18228
6916
13304
13688
13628
5948
2、jstat :
JVM Statistics Monitoring Tool:虚拟机统计信息监控工具) :
用于监视虚拟机各种运行状态信息的命令行工具,可以显示本地或者是远程虚拟机进程中的类加载,内存,垃圾收集,在没有GUI图形页面,踏实运行期定位虚拟机性能的首选工具
| 命令 | 说明 |
|---|---|
jstat -class |
用于查看类加载情况的统计,显示加载class的数量,及所占空间等信息。 |
jstat -compiler |
JIT,查看HotSpot中即时编译器编译情况的统计 |
jstat -gc |
GC 堆状态,查看JVM中堆的垃圾收集情况的统计,可以显示gc的信息,查看gc的次数,及时间。其中最后五项,分别是young gc的次数,young gc的时间,full gc的次数,full gc的时间,gc的总时间。 |
jstat -gccapacity |
各区大小,查看新生代、老生代及持久代的存储容量情况,可以显示,VM内存中三代(young,old,perm)对象的使用和占用大小 |
jstat -gccause |
最近一次 GC 统计和原因,查看垃圾收集的统计情况(这个和-gcutil选项一样),如果有发生垃圾收集,它还会显示最后一次及当前正在发生垃圾收集的原因 |
| jstat -gcnew | 新区统计,查看新生代垃圾收集的情况,年轻代对象的信息 |
| jstat -gcnewcapacity | 年轻代内存统计 |
| jstat -gcold | 老年代垃圾回收统计,用于查看老生代及持久代发生GC的情况,老年代对象的信息 |
jstat -gcoldcapacity |
老区大小,用于查看老生代的容量,old对象的信息及其占用量 |
| jstat -gcpermcapacity | 永久区大小,用于查看持久代的容量,perm对象的信息及其占用量 |
jstat -gcutil |
GC统计汇总,查看新生代、老生代及持代垃圾收集的情况 |
| jstat -printcompilation | HotSpot编译统计,当前VM执行的信息 |
1)jstat -class pid :
查看类加载情况的统计
[work@vm10-123-3-2 bin]$ ./jstat -class 12566
Loaded Bytes Unloaded Bytes Time
17604 34620.3 0 0.0 20.28
| 参数 | 说明 |
|---|---|
Loaded |
加载class的数量 |
Bytes |
所占用空间大小 |
Unloaded |
未加载数量 |
Bytes |
未加载占用空间 |
Time |
时间 |
2)jstat -gc pid time num:
实时监控
GC容量举例:每
3秒收集一次进程为12566的垃圾收集状况,一共查询100次
[work@vm10-123-3-2 bin]$ ./jstat -gc 12566 3000 100
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
26176.0 26176.0 0.0 1859.9 209792.0 159325.8 786432.0 168717.4 116168.0 110226.9 13108.0 12151.5 283 6.863 5 0.230 7.093
26176.0 26176.0 0.0 1859.9 209792.0 34511.3 786432.0 168717.4 116168.0 110226.9 13108.0 12151.5 283 6.863 5 0.230 7.093
26176.0 26176.0 0.0 1859.9 209792.0 34513.3 786432.0 168717.4 116168.0 110226.9 13108.0 12151.5 283 6.863 5 0.230 7.093
26176.0 26176.0 0.0 1859.9 209792.0 36273.8 786432.0 168717.4 116168.0 110226.9 13108.0 12151.5 283 6.863 5 0.230 7.093
26176.0 26176.0 0.0 1859.9 209792.0 36273.8 786432.0 168717.4 116168.0 110226.9 13108.0 12151.5 283 6.863 5 0.230 7.093
26176.0 26176.0 0.0 1859.9 209792.0 36273.8 786432.0 168717.4 116168.0 110226.9 13108.0 12151.5 283 6.863 5 0.230 7.093
26176.0 26176.0 0.0 1859.9 209792.0 36273.8 786432.0 168717.4 116168.0 110226.9 13108.0 12151.5 283 6.863 5 0.230 7.093
26176.0 26176.0 0.0 1859.9 209792.0 36275.9 786432.0 168717.4 116168.0 110226.9 13108.0 12151.5 283 6.863 5 0.230 7.093
26176.0 26176.0 0.0 1859.9 209792.0 36275.9 786432.0 168717.4 116168.0 110226.9 13108.0 12151.5 283 6.863 5 0.230 7.093
26176.0 26176.0 0.0 1859.9 209792.0 36288.9 786432.0 168717.4 116168.0 110226.9 13108.0 12151.5 283 6.863 5 0.230 7.093
26176.0 26176.0 0.0 1859.9 209792.0 36288.9 786432.0 168717.4 116168.0 110226.9 13108.0 12151.5 283 6.863 5 0.230 7.093
26176.0 26176.0 0.0 1859.9 209792.0 36288.9 786432.0 168717.4 116168.0 110226.9 13108.0 12151.5 283 6.863 5 0.230 7.093
26176.0 26176.0 0.0 1859.9 209792.0 36288.9 786432.0 168717.4 116168.0 110226.9 13108.0 12151.5 283 6.863 5 0.230 7.093

| 参数 | 说明(单位是KB) |
|---|---|
| S0C、S1C、S0U、S1U | Survivor 0/1区容量(Capacity)和使用量(Used) |
| EC、EU | Eden区容量和使用量 |
| OC、OU | 年老代容量和使用量 |
| MC | 元空间commited容量,是commited,并不是capacity, |
| MU | 元空间used的容量 |
| CCSC | 压缩类空间 class space 中 commited容量, 是commited,并不是capacity |
| CCSU | 压缩类空间 class space 中 used容量 |
| YGC、YGCT | 年轻代GC次数和GC耗时 |
| FGC、FGCT | Full GC次数和Full GC耗时 |
| GCT | GC总耗时 |
3)jstat -gcutil pid time num:
实时监控
GC百分比举例:每
3秒收集一次进程为12566的垃圾收集状况,一共查询100次
[work@vm10-123-3-2 bin]$ ./jstat -gcutil 12566 3000 100
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.00 7.11 66.31 21.45 94.89 92.70 283 6.863 5 0.230 7.093
0.00 7.11 66.31 21.45 94.89 92.70 283 6.863 5 0.230 7.093
0.00 7.11 66.31 21.45 94.89 92.70 283 6.863 5 0.230 7.093
0.00 7.11 66.31 21.45 94.89 92.70 283 6.863 5 0.230 7.093
0.00 7.11 66.31 21.45 94.89 92.70 283 6.863 5 0.230 7.093
0.00 7.11 66.31 21.45 94.89 92.70 283 6.863 5 0.230 7.093
0.00 7.11 66.31 21.45 94.89 92.70 283 6.863 5 0.230 7.093
0.00 7.11 66.31 21.45 94.89 92.70 283 6.863 5 0.230 7.093
0.00 7.11 66.31 21.45 94.89 92.70 283 6.863 5 0.230 7.093
0.00 7.11 66.32 21.45 94.89 92.70 283 6.863 5 0.230 7.093

| 参数 | 说明 |
|---|---|
| S0 S1 | Survivor 0/1 占用百分比 |
| E | Eden 所占百分比 |
| O | 老年代 所占百分比 |
| M | 元数据区已使用的占当前容量百分比,MC/MU计算出来的 |
| CCS | 压缩类空间使用的占当前容量百分比,NoKlass Metaspace的使用率,也就是CCSU/CCSC算出来的 |
| YGC | 年轻代GC次数 |
| YGCT | 年轻代GC时间 |
| FGC | 老年代GC次数 |
| FGCT | 老年代GC时间 |
| GCT | GC总耗时 |
4)jstat -gcnewcapacity pid:
年轻代内存统计
[work@vm10-123-3-2 bin]$ ./jstat -gcnewcapacity 12566
NGCMN NGCMX NGC S0CMX S0C S1CMX S1C ECMX EC YGC FGC
262144.0 262144.0 262144.0 26176.0 26176.0 26176.0 26176.0 209792.0 209792.0 284 5

| 参数 | 说明 |
|---|---|
| NGCMN、NGCMX | 年轻代最小容量、最大容量 |
| NGC | 当前年轻代容量 |
| S0CMX、S1CMX | Survivor0/1 最大容量 |
| S0C、S1C | 当前Survivor0/1 容量 |
| ECMX | Eden最大容量 |
| EC | 当前Eden容量 |
| YGC | 年轻代gc次数 |
| FGC | 老年代gc次数 |
5)jstat -gcnew pid:
年轻代垃圾回收统计
[work@vm10-123-3-2 bin]$ ./jstat -gcnew 12566
S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT
26176.0 26176.0 0.0 1859.9 10 10 13088.0 209792.0 209614.9 283 6.863
| 参数 | 说明 |
|---|---|
| S0C、S1C | Survivor 0/1 容量大小 |
| S0U、S1U | Survivor 0/1 使用量大小 |
| TT | 对象在年轻代存活的次数 |
| MTT | 对象在新生代存活的最大次数 |
| DSS | 当前期望的Survivor大小(伊甸园区已满) |
| EC、EU | Eden 容量和使用量大小 |
| YGC | 年轻代gc次数 |
| YGCT | 年轻代gc时消耗时间 |
6)jstat -gcoldcapacity pid:
老年代内存统计
[work@vm10-123-3-2 bin]$ ./jstat -gcoldcapacity 12566
OGCMN OGCMX OGC OC YGC FGC FGCT GCT
786432.0 786432.0 786432.0 786432.0 284 5 0.230 7.117
| 参数 | 说明 |
|---|---|
| OGCMN、OGCMX | 老年代最小容量、最大容量 |
| OGC | 老年代当前容量 |
| OC | 老年代当前容量 |
| YGC | 年轻代gc次数 |
| FGC | 老年代gc次数 |
| FGCT | 老年代gc时消耗时间 |
| GCT | gc消耗总时间 |
7)jstat -gcold pid :
老年代垃圾回收统计
[work@vm10-123-3-2 bin]$ ./jstat -gcold 12566
MC MU CCSC CCSU OC OU YGC FGC FGCT GCT
116168.0 110279.2 13108.0 12151.5 786432.0 168717.5 284 5 0.230 7.117
| 参数 | 说明 |
|---|---|
| MC | 元空间commited容量,是commited,并不是capacity |
| MU | 元空间used的容量 |
| CCSC | 压缩类空间class space 中 commited容量, 是commited,并不是capacity** |
| CCSU | 压缩类空间class space 中 used容量 |
| OC、OU | 老年代容量、老年代使用容量 |
| YGC | 年轻代gc次数 |
| FGC | 老年代gc次数 |
| FGCT | 老年代gc时消耗时间 |
| GCT | gc消耗总时间 |
8)jstat -gcmetacapacity pid:
元数据内存统计
[work@vm10-123-3-2 bin]$ ./jstat -gcmetacapacity 12566
MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC FGCT GCT
0.0 1153024.0 116168.0 0.0 1048576.0 13108.0 284 5 0.230 7.117
| 参数 | 说明 |
|---|---|
| MCMN | 最小元数据容量(0) |
| MCMX | 最大元数据容量:元空间 reserved值 |
| MC | 元空间commited容量,是commited,并不是capacity |
| CCSM、 | 最小压缩类空间容量(0) |
| CCSMX | 最大压缩类空间容量(压缩类空间class space 中 reserved的内存大小) |
| CCSC | 压缩类空间class space 中 commited容量, 是commited,并不是capacity |
| YGC | 年轻代gc次数 |
| FGC | 老年代gc次数 |
| FGCT | 老年代gc时消耗时间 |
| GCT | gc消耗总时间 |
3、jstack pid:
显示虚拟机的线程快照,定位死循环、线程阻塞、死锁等问题
$ jstack 21048
1)死循环
public class Jvm04_01jps {
public static void main(String[] args) throws InterruptedException {
method();
}
public static void method(){
while (true) {
}
}
}

2)object.wait(),
class TestTask implements Runnable {
@Override
public void run() {
synchronized (this) {
try {
//等待被唤醒
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
ExecutorService ex = Executors.newFixedThreadPool(1);
ex.execute(new TestTask());
}
}

3)死锁
class TestTask implements Runnable {
private Object obj1;
private Object obj2;
private int order;
public TestTask(int order, Object obj1, Object obj2) {
this.order = order;
this.obj1 = obj1;
this.obj2 = obj2;
}
public void test1() throws InterruptedException {
synchronized (obj1) {
//建议线程调取器切换到其它线程运行
Thread.yield();
synchronized (obj2) {
System.out.println("test。。。");
}
}
}
public void test2() throws InterruptedException {
synchronized (obj2) {
Thread.yield();
synchronized (obj1) {
System.out.println("test。。。");
}
}
}
@Override
public void run() {
while (true) {
try {
if(this.order == 1){
this.test1();
}else{
this.test2();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
Object obj1 = new Object();
Object obj2 = new Object();
ExecutorService ex = Executors.newFixedThreadPool(10);
// 起10个线程
for (int i = 0; i < 10; i++) {
int order = i%2==0 ? 1 : 0;
ex.execute(new TestTask(order, obj1, obj2));
}
}
}

4、jinfo:
实时查看
Java系统和调整JVM的各项参数 可以用来查看正在运行的 java 应用程序的扩展参数,包括Java System属性和JVM命令行参数;也可以动态的修改正在运行的 JVM 一些参数。
1)jinfo pid:
输出当前 jvm 进程的全部参数和系统属性
[work@vm10-123-3-2 bin]$ ./jinfo 12566
Attaching to process ID 12566, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.202-b08
Java System Properties:
com.sun.management.jmxremote.authenticate = false
java.runtime.name = OpenJDK Runtime Environment
java.vm.version = 25.202-b08
sun.boot.library.path = /usr/local/service/app/scf/scf-manager/jdk1.8.0_202/jre/lib/amd64
javax.management.builder.initial = com.caucho.jmx.MBeanServerBuilderImpl
java.vendor.url = https://adoptopenjdk.net/
java.vm.vendor = Oracle Corporation
path.separator = :
java.rmi.server.randomIDs = true
file.encoding.pkg = sun.io
java.vm.name = OpenJDK 64-Bit Server VM
sun.os.patch.level = unknown
sun.java.launcher = SUN_STANDARD
user.country = US
user.dir = /usr/local/service/app/scf/scf-manager/resin-pro-4.0.58/bin
java.vm.specification.name = Java Virtual Machine Specification
com.sun.management.jmxremote.port = 8393
java.runtime.version = 1.8.0_202-b08
java.awt.graphicsenv = sun.awt.X11GraphicsEnvironment
os.arch = amd64
java.endorsed.dirs = /usr/local/service/app/scf/scf-manager/jdk1.8.0_202/jre/lib/endorsed:/usr/local/service/app/scf/scf-manager/resin-pro-4.0.58/endorsed
line.separator =
java.io.tmpdir = /tmp
java.vm.specification.vendor = Oracle Corporation
java.util.logging.manager = com.caucho.log.LogManagerImpl
java.naming.factory.url.pkgs = com.caucho.naming
os.name = Linux
resin.home = /usr/local/service/app/scf/scf-manager/resin-pro-4.0.58
sun.jnu.encoding = UTF-8
java.system.class.loader = com.caucho.loader.SystemClassLoader
java.library.path = /usr/local/service/app/scf/scf-manager/jdk1.8.0_202/jre/lib/amd64/server:/usr/local/service/app/scf/scf-manager/jdk1.8.0_202/jre/lib/amd64:/usr/local/service/app/scf/scf-manager/jdk1.8.0_202/jre/../lib/amd64:/usr/local/service/app/scf/scf-manager/resin-pro-4.0.58/libexec64:/usr/local/service/app/scf/scf-manager/jdk1.8.0_202/jre/lib/amd64/server:/usr/local/service/app/scf/scf-manager/jdk1.8.0_202/jre/lib/amd64:/usr/local/service/app/scf/scf-manager/jdk1.8.0_202/lib/amd64:/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
java.specification.name = Java Platform API Specification
java.class.version = 52.0
sun.management.compiler = HotSpot 64-Bit Tiered Compilers
os.version = 3.10.0-514.26.2.el7.x86_64
user.home = /home/work
user.timezone =
java.awt.printerjob = sun.print.PSPrinterJob
file.encoding = UTF-8
java.specification.version = 1.8
user.name = work
java.class.path = /usr/local/service/app/scf/scf-manager/resin-pro-4.0.58/lib/resin.jar:.:/usr/local/service/app/scf/scf-manager/jdk1.8.0_202/lib/tools.jar:/usr/local/service/app/scf/scf-manager/jdk1.8.0_202/lib/rt.jar:/usr/local/service/app/scf/scf-manager/resin-pro-4.0.58/lib/eclipselink-2.4.0.jar:/usr/local/service/app/scf/scf-manager/resin-pro-4.0.58/lib/javax.faces-2.1.24.jar:/usr/local/service/app/scf/scf-manager/resin-pro-4.0.58/lib/webservices-extra-api.jar:/usr/local/service/app/scf/scf-manager/resin-pro-4.0.58/lib/javamail-141.jar:/usr/local/service/app/scf/scf-manager/resin-pro-4.0.58/lib/webutil.jar:/usr/local/service/app/scf/scf-manager/resin-pro-4.0.58/lib/javaee-16.jar:/usr/local/service/app/scf/scf-manager/resin-pro-4.0.58/lib/resin.jar:/usr/local/service/app/scf/scf-manager/resin-pro-4.0.58/lib/pro.jar:/usr/local/service/app/scf/scf-manager/resin-pro-4.0.58/lib/resin-eclipselink.jar:/usr/local/service/app/scf/scf-manager/resin-pro-4.0.58/lib/activation.jar
java.naming.factory.initial = com.caucho.naming.InitialContextFactoryImpl
com.sun.management.jmxremote =
java.vm.specification.version = 1.8
sun.arch.data.model = 64
sun.java.command = com.caucho.server.resin.Resin --root-directory /usr/local/service/app/scf/scf-manager/resin-pro-4.0.58 -conf ./../conf/resin.xml -server scf-manager start
java.home = /usr/local/service/app/scf/scf-manager/jdk1.8.0_202/jre
user.language = en
java.specification.vendor = Oracle Corporation
awt.toolkit = sun.awt.X11.XToolkit
com.sun.management.jmxremote.ssl = false
java.vm.info = mixed mode
java.version = 1.8.0_202
java.ext.dirs = /usr/local/service/app/scf/scf-manager/jdk1.8.0_202/jre/lib/ext:/usr/java/packages/lib/ext
sun.boot.class.path = /usr/local/service/app/scf/scf-manager/jdk1.8.0_202/jre/lib/resources.jar:/usr/local/service/app/scf/scf-manager/jdk1.8.0_202/jre/lib/rt.jar:/usr/local/service/app/scf/scf-manager/jdk1.8.0_202/jre/lib/sunrsasign.jar:/usr/local/service/app/scf/scf-manager/jdk1.8.0_202/jre/lib/jsse.jar:/usr/local/service/app/scf/scf-manager/jdk1.8.0_202/jre/lib/jce.jar:/usr/local/service/app/scf/scf-manager/jdk1.8.0_202/jre/lib/charsets.jar:/usr/local/service/app/scf/scf-manager/jdk1.8.0_202/jre/lib/jfr.jar:/usr/local/service/app/scf/scf-manager/jdk1.8.0_202/jre/classes
java.awt.headless = true
java.vendor = AdoptOpenJdk
file.separator = /
java.vendor.url.bug = https://github.com/AdoptOpenJDK/openjdk-build/issues
sun.io.unicode.encoding = UnicodeLittle
sun.cpu.endian = little
log4j2.isThreadContextMapInheritable = true
sun.cpu.isalist =
VM Flags:
Non-default VM flags: -XX:CICompilerCount=12 -XX:CMSFullGCsBeforeCompaction=50 -XX:InitialHeapSize=1073741824 -XX:+ManagementServer -XX:MaxHeapSize=1073741824 -XX:MaxNewSize=268435456 -XX:MaxTenuringThreshold=10 -XX:MinHeapDeltaBytes=196608 -XX:NewSize=268435456 -XX:OldPLABSize=16 -XX:OldSize=805306368 -XX:+PrintFlagsFinal -XX:+PrintGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:SurvivorRatio=8 -XX:+UseCMSCompactAtFullCollection -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:+UseParNewGC
Command line: -Xmn256M -Xmx1024M -Xms1024M -XX:MaxPermSize=256M -XX:PermSize=256M -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC -XX:CMSFullGCsBeforeCompaction=50 -XX:+UseCMSCompactAtFullCollection -XX:MaxTenuringThreshold=10 -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintFlagsFinal -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8393 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Xloggc:/usr/local/service/log/scf/scf-manager/gc.log -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=19137 -Dlog4j2.isThreadContextMapInheritable=true -Djava.util.logging.manager=com.caucho.log.LogManagerImpl -Djava.system.class.loader=com.caucho.loader.SystemClassLoader -Djava.endorsed.dirs=/usr/local/service/app/scf/scf-manager/jdk1.8.0_202/jre/lib/endorsed:/usr/local/service/app/scf/scf-manager/resin-pro-4.0.58/endorsed -Djavax.management.builder.initial=com.caucho.jmx.MBeanServerBuilderImpl -Djava.awt.headless=true -Dresin.home=/usr/local/service/app/scf/scf-manager/resin-pro-4.0.58
2)jinfo -flag pid :
开启/关闭、设置对应名称的参数、显示Jvm参数值包括默认值
使用 jinfo 可以在不重启虚拟机的情况下,可以动态的修改 jvm 的参数。尤其在线上的环境特别有用。
A、jinfo -flags pid
打印所有JVM参数(包括默认值 )
[work@vm10-123-3-2 bin]$ ./jinfo -flags 12566
Attaching to process ID 12566, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.202-b08
Non-default VM flags:
-XX:CICompilerCount=12
-XX:CMSFullGCsBeforeCompaction=50
-XX:InitialHeapSize=1073741824
-XX:+ManagementServer
-XX:MaxHeapSize=1073741824
-XX:MaxNewSize=268435456
-XX:MaxTenuringThreshold=10
-XX:MinHeapDeltaBytes=196608
-XX:NewSize=268435456
-XX:OldPLABSize=16
-XX:OldSize=805306368
-XX:+PrintFlagsFinal
-XX:+PrintGC
-XX:+PrintGCDateStamps
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:SurvivorRatio=8
-XX:+UseCMSCompactAtFullCollection
-XX:+UseCompressedClassPointers
-XX:+UseCompressedOops
-XX:+UseConcMarkSweepGC
-XX:+UseParNewGC
Command line: -Xmn256M -Xmx1024M -Xms1024M -XX:MaxPermSize=256M -XX:PermSize=256M -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC -XX:CMSFullGCsBeforeCompaction=50 -XX:+UseCMSCompactAtFullCollection -XX:MaxTenuringThreshold=10 -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintFlagsFinal -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8393 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Xloggc:/usr/local/service/log/scf/scf-manager/gc.log -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=19137 -Dlog4j2.isThreadContextMapInheritable=true -Djava.util.logging.manager=com.caucho.log.LogManagerImpl -Djava.system.class.loader=com.caucho.loader.SystemClassLoader -Djava.endorsed.dirs=/usr/local/service/app/scf/scf-manager/jdk1.8.0_202/jre/lib/endorsed:/usr/local/service/app/scf/scf-manager/resin-pro-4.0.58/endorsed -Djavax.management.builder.initial=com.caucho.jmx.MBeanServerBuilderImpl -Djava.awt.headless=true -Dresin.home=/usr/local/service/app/scf/scf-manager/resin-pro-4.0.58
[work@vm10-123-3-2 bin]$
B、显示指定的Jvm参数值(包括默认值)。
$ jinfo -flag MaxTenuringThreshold 21048
-XX:MaxTenuringThreshold=15
$ jinfo -flag PrintGCDetails 21048
-XX:-PrintGCDetails
java -XX:+PrintFlagsFinal -version | grep MetaspaceSiz
C、指定参数的值
jinfo -flag MaxTenuringThreshold=10 21048
D、开启或者关闭日志
jinfo -flag +PrintGC 21048
jinfo -flag +PrintGCDetails 21048
jinfo -flag -PrintGC 21048
jinfo -flag -PrintGCDetails 21048
5、jmap
生成虚拟机的堆转储快照(heapdump文件)
| 命令 | 说明 |
|---|---|
jmap -heap |
显示java堆详细信息,如使用哪种收集器、参数配置、分代情况等,在Linux/Solaris平台下有效 |
jmap -histo |
显示堆对象简单的统计报表 |
jmap -dump |
打印整个堆快照 |
1)jmap -heap pid :
显示
Java堆详细信息
Attaching to process ID 1119, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.322-b1
using thread-local object allocation.
Garbage-First (G1) GC with 4 thread(s)
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 5582618624 (5324.0MB)
NewSize = 1363144 (1.2999954223632812MB)
MaxNewSize = 3349151744 (3194.0MB)
OldSize = 5452592 (5.1999969482421875MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 536870912 (512.0MB)
CompressedClassSpaceSize = 528482304 (504.0MB)
MaxMetaspaceSize = 536870912 (512.0MB)
G1HeapRegionSize = 2097152 (2.0MB)
Heap Usage:
G1 Heap:
regions = 2662
capacity = 5582618624 (5324.0MB)
used = 1586867760 (1513.3550262451172MB)
free = 3995750864 (3810.644973754883MB)
28.425150755918803% used
G1 Young Generation:
Eden Space:
regions = 626
capacity = 3508535296 (3346.0MB)
used = 1312817152 (1252.0MB)
free = 2195718144 (2094.0MB)
37.4178123132098% used
Survivor Space:
regions = 4
capacity = 8388608 (8.0MB)
used = 8388608 (8.0MB)
free = 0 (0.0MB)
100.0% used
G1 Old Generation:
regions = 131
capacity = 2065694720 (1970.0MB)
used = 263564848 (251.3550262451172MB)
free = 1802129872 (1718.6449737548828MB)
12.759138388077014% used
89848 interned Strings occupying 10065232 bytes.
a、基础信息
Attaching to process ID 1119, please wait...:正在尝试连接进程ID为1119的Java进程(通常是通过jmap或调试工具获取堆信息)。Debugger attached successfully.:调试工具已成功连接到目标进程。Server compiler detected.:检测到JVM使用的是服务器端编译器(Server Compiler),适用于长时间运行的服务端应用,编译优化更激进。JVM version is 25.322-b1:JVM版本信息,这里是Java 8(版本号25对应Java 8),具体更新版本为 322-b1。
b、GC 与线程配置
using thread-local object allocation:JVM使用线程本地分配缓冲区(TLAB,Thread-Local Allocation Buffer),减少多线程分配对象时的锁竞争,提高分配效率。Garbage-First (G1) GC with 4 thread(s):采用G1垃圾收集器(Garbage-First GC),配置了4个GC线程(用于并行处理垃圾回收任务)。
c、堆配置(Heap Configuration)
堆配置参数定义了
JVM堆内存的初始、最大、比例等规则,由 JVM 启动参数(如-Xms、-Xmx)或默认值决定。
MinHeapFreeRatio= 40:堆内存最小空闲比例。堆空闲空间低于40%时,JVM会自动扩展堆大小(直到达到MaxHeapSize)。MaxHeapFreeRatio= 70:堆内存最大空闲比例。堆空闲空间高于70%时,JVM会自动收缩堆大小(直到不低于MinHeapSize)。MaxHeapSize=5582618624(5324.0MB):堆内存的最大允许大小,由启动参数-Xmx5324m指定或默认计算得出NewSize=1363144(1.2999954223632812MB):新生代的初始大小,约13MB(G1中该值通常由JVM动态调整,默认值较小)MaxNewSize=3349151744(3194.0MB):新生代的最大允许大小,约3194MB。G1中新生代大小会动态变化,但不超过此值。OldSize= 5452592 (5.1999969482421875MB):老年代的初始大小,约5.2MB(G1中老年代大小同样动态调整)。NewRatio= 2:老年代与新生代的大小比例(老年代:新生代 = 2:1)。这里表示老年代最大可占堆内存的 2/3,新生代占 1/3(需结合MaxHeapSize和MaxNewSize理解)。SurvivorRatio= 8:新生代中Eden区与Survivor区的比例(Eden:Survivor=8:1)。- 例如,若新生代总大小为
9MB,则 Eden 区8MB,两个Survivor区各 0.5MB(实际使用时只启用一个 Survivor 区)。
- 例如,若新生代总大小为
MetaspaceSize= 536870912 (512.0MB):元空间(Metaspace)的初始大小,约512MB。元空间用于存储类元数据(如类结构、方法信息等),与Java 7及之前的永久代(PermGen)功能类似,但元空间直接使用本地内存。CompressedClassSpaceSize= 528482304 (504.0MB):压缩类空间的最大大小,约 504MB。当启用类指针压缩(默认开启,除非堆大小超过 32GB)时,类元数据会存储在该空间中,受此参数限制。MaxMetaspaceSize= 536870912 (512.0MB):元空间的最大允许大小,约 512MB。若类加载过多导致元空间超过此值,会触发OutOfMemoryError: Metaspace。G1HeapRegionSize= 2097152 (2.0MB):G1收集器将堆内存划分为多个大小相等的区域(Region)- 每个区域大小为
2MB。区域大小会影响G1的垃圾回收效率 - 小区域适合处理大量小对象,大区域适合大对象
- 每个区域大小为
d、堆使用情况(Heap Usage)
实时堆内存的分配和使用状态,反映当前内存消耗情况。
G1 Heap:G1 收集器管理的整个堆内存汇总信息。regions= 2662:堆内存被划分为 2662 个 G1 区域(每个区域 2MB,总大小 2662×2MB=5324MB,与MaxHeapSize一致)。capacity= 5582618624 (5324.0MB):堆内存的总容量(即MaxHeapSize,5324MB)。used= 1586867760 (1513.3550262451172MB):当前堆内存已使用大小,约 1513MB。free= 3995750864 (3810.644973754883MB):当前堆内存空闲大小,约 3810MB。28.425150755918803% used:堆内存整体使用率约 28.4%(已使用 / 总容量)。
G1 Young Generation:G1新生代的使用情况(新生代包含Eden区和Survivor区,用于存放新创建的对象)。EdenSpace:新生代中的Eden区(对象首次分配的区域)。- regions = 626:Eden 区 已占用 626 个 G1 区域(626×2MB=1252MB)。
- capacity = 3508535296 (3346.0MB):Eden 区的总容量(即当前新生代可分配的最大空间)。
- used = 1312817152 (1252.0MB):Eden 区已使用大小(与区域数计算结果一致,626×2MB=1252MB)。
- free = 2195718144 (2094.0MB):Eden 区空闲大小(总容量 - 已使用)。
- 37.4178123132098% used:Eden 区使用率约 37.4%。
Survivor Space::新生代中的 Survivor 区(用于存放 Eden 区 GC 后存活的对象)。regions= 4:Survivor 区占用 4 个 G1 区域(4×2MB=8MB)。capacity= 8388608 (8.0MB)Survivor 区总容量(G1 中通常为新生代的 1/10,由SurvivorRatio决定)。used= 8388608 (8.0MB):Survivor 区已使用大小(当前完全占满,说明最近一次 Minor GC 后有较多对象存活)。free= 0 (0.0MB):Survivor 区空闲大小(当前为 0,已完全使用)。100.0%used:Survivor 区使用率 100%(需注意:Survivor 区满后,存活对象会进入老年代)。
G1 Old Generation:G1 老年代的使用情况(存放长期存活或大对象,新生代 GC 后仍存活的对象会逐渐进入老年代)。- regions = 131:老年代占用 131 个 G1 区域(131×2MB=262MB)。
- capacity = 2065694720 (1970.0MB):老年代的总容量(堆总容量 - 新生代容量 = 5324MB-3346MB=1978MB,此处 1970MB 为动态调整后的值)。
- used = 263564848 (251.3550262451172MB):老年代已使用大小,约 251MB。
- free = 1802129872 (1718.6449737548828MB):老年代空闲大小,约 1718MB。
- 12.759138388077014% used:老年代使用率约 12.8%(较低,说明对象存活时间短,GC 效率较好)。
- 89848 interned Strings occupying 10065232 bytes.:
JVM中已intern的字符串(字符串常量池中的字符串)数量为 89848 个,总占用内存约 10065232 字节(约 9.6MB)。字符串intern机制用于复用相同字符串对象,减少内存占用。
2) jmap -histo pid:
显示堆对象简单的统计报表,
jmap-histopid
jmap-histo:livepid:只统计活的,使用live,JVM会先触发fullgc,然后再统计信息。所以如果不是很有必要的话,不要去执行
jmap -histo:live pid>a.log 可以将其保存到文本中去,在一段时间后,使用文本对比工具,可以对比出GC回收了哪些对象。
然而这个只知道哪些对象有多少个,占用了多大的内存,但不知道由什么对象创建的。下一步需要使用命令 jmap -dump将快照打印出来出来,使用内存分析工具进一步明确它是由谁引用的、由什么对象。
| 符号 | 说明 |
|---|---|
| B | byte |
| C | char |
| D | double |
| F | float |
| I | int |
| J | long |
| Z | boolean |
| [ | [ 代表数组, [I 就相当于 int[] |
| [L+ 类名表示 | 对象用 [L+ 类名表示 |
instances(实例数)、bytes(大小)、classs name(类名)。它基本是按照使用使用大小逆序排列的。
$ jmap -histo:live 21048
num #instances #bytes class name
----------------------------------------------
1: 4915 554288 [C
2: 679 262448 [B
3: 4767 114408 java.lang.String
4: 681 77752 java.lang.Class
5: 681 46520 [Ljava.lang.Object;
6: 791 31640 java.util.TreeMap$Entry
7: 419 13408 java.util.HashMap$Node
8: 203 12992 java.net.URL
9: 262 12272 [Ljava.lang.String;
10: 290 11600 java.lang.ref.Finalizer
11: 133 7688 [I
12: 166 6640 java.util.LinkedHashMap$Entry
13: 67 6432 java.util.jar.JarFile$JarFileEntry
14: 75 6000 [Ljava.util.WeakHashMap$Entry;
15: 99 5544 sun.misc.URLClassPath$JarLoader
16: 21 5328 [Ljava.util.HashMap$Node;
17: 72 4608 java.util.jar.JarFile
18: 109 4360 java.lang.ref.SoftReference
19: 74 4144 sun.nio.cs.UTF_8$Encoder
20: 256 4096 java.lang.Integer
21: 72 4032 java.util.zip.ZipFile$ZipFileInputStream
22: 166 3984 java.io.ExpiringCache$Entry
23: 123 3936 java.util.Hashtable$Entry
24: 66 3696 java.util.zip.ZipFile$ZipFileInflaterInputStream
25: 75 3600 java.util.WeakHashMap
26: 104 3328 java.util.concurrent.ConcurrentHashMap$Node
27: 66 3168 java.util.zip.Inflater
28: 8 3008 java.lang.Thread
29: 69 2760 sun.nio.cs.UTF_8$Decoder
30: 82 2624 java.lang.ref.ReferenceQueue
31: 72 2304 java.util.zip.ZipCoder
32: 26 2080 java.lang.reflect.Constructor
33: 15 1968 [Ljava.util.concurrent.ConcurrentHashMap$Node;
34: 39 1872 sun.util.locale.LocaleObjectCache$CacheEntry
35: 72 1728 java.util.ArrayDeque
36: 66 1584 java.util.zip.ZStreamRef
37: 1 1568 [[B
38: 37 1480 java.io.ObjectStreamField
39: 87 1392 java.lang.Object
40: 29 1392 java.util.HashMap
41: 84 1344 java.lang.ref.ReferenceQueue$Lock
42: 19 1216 java.util.concurrent.ConcurrentHashMap
43: 9 1184 [Ljava.util.Hashtable$Entry;
44: 2 1064 [Ljava.lang.invoke.MethodHandle;
45: 1 1040 [Ljava.lang.Integer;
46: 1 1040 [[C
47: 19 760 sun.util.locale.BaseLocale$Key
48: 8 640 [S
49: 19 608 java.util.Locale
50: 19 608 sun.util.locale.BaseLocale
51: 18 576 java.io.File
52: 13 520 java.security.AccessControlContext
53: 19 456 java.util.Locale$LocaleKey
54: 17 408 java.util.jar.Attributes$Name
55: 13 392 [Ljava.io.ObjectStreamField;
56: 1 384 com.intellij.rt.execution.application.AppMainV2$1
57: 1 384 java.lang.ref.Finalizer$FinalizerThread
58: 6 384 java.nio.DirectByteBuffer
59: 16 384 sun.misc.MetaIndex
60: 1 376 java.lang.ref.Reference$ReferenceHandler
61: 9 360 java.io.FileDescriptor
62: 6 336 java.nio.DirectLongBufferU
63: 14 336 java.util.LinkedList$Node
64: 10 320 java.lang.OutOfMemoryError
65: 3 312 [D
66: 13 312 sun.reflect.NativeConstructorAccessorImpl
67: 2 296 [J
68: 15 280 [Ljava.lang.Class;
69: 5 280 sun.util.calendar.ZoneInfo
70: 11 264 java.util.ArrayList
71: 8 256 java.util.LinkedList
72: 8 256 java.util.Vector
73: 3 240 [Ljava.lang.ThreadLocal$ThreadLocalMap$Entry;
74: 5 240 java.util.Hashtable
75: 6 240 java.util.WeakHashMap$Entry
76: 13 208 sun.reflect.DelegatingConstructorAccessorImpl
77: 5 200 java.security.ProtectionDomain
78: 6 192 java.io.FileInputStream
79: 6 192 java.lang.ThreadLocal$ThreadLocalMap$Entry
80: 4 192 java.util.Properties
81: 4 192 java.util.TreeMap
82: 2 160 [[Ljava.lang.String;
83: 4 160 java.lang.ClassLoader$NativeLibrary
84: 5 160 java.security.CodeSource
85: 5 160 sun.util.locale.provider.LocaleProviderAdapter$Type
86: 3 144 java.nio.HeapByteBuffer
87: 6 144 sun.misc.PerfCounter
88: 3 144 sun.misc.URLClassPath
89: 2 128 java.io.ExpiringCache$1
90: 4 128 java.util.Stack
91: 1 120 java.net.SocksSocketImpl
92: 5 120 java.util.Collections$UnmodifiableRandomAccessList
93: 5 120 sun.misc.FloatingDecimal$PreparedASCIIToBinaryBuffer
94: 2 112 java.lang.Package
95: 2 112 java.util.LinkedHashMap
96: 2 112 java.util.ResourceBundle$CacheKey
97: 4 96 java.lang.RuntimePermission
98: 2 96 java.lang.ThreadGroup
99: 3 96 java.lang.ref.WeakReference
100: 2 96 java.util.ResourceBundle$BundleReference
101: 1 96 sun.misc.Launcher$AppClassLoader
102: 3 96 sun.net.spi.DefaultProxySelector$NonProxyInfo
103: 2 96 sun.nio.cs.StreamEncoder
104: 1 88 java.net.DualStackPlainSocketImpl
105: 1 88 sun.misc.Launcher$ExtClassLoader
106: 5 80 [Ljava.security.Principal;
107: 2 80 java.io.BufferedWriter
108: 2 80 java.io.ExpiringCache
109: 5 80 java.lang.ThreadLocal
110: 5 80 java.security.ProtectionDomain$Key
111: 2 80 sun.misc.FloatingDecimal$BinaryToASCIIBuffer
112: 3 72 java.lang.ThreadLocal$ThreadLocalMap
113: 3 72 java.net.Proxy$Type
114: 3 72 java.util.Arrays$ArrayList
115: 3 72 java.util.Collections$SynchronizedSet
116: 1 72 java.util.ResourceBundle$RBClassLoader
117: 3 72 java.util.concurrent.atomic.AtomicLong
118: 3 72 sun.misc.FloatingDecimal$ExceptionalBinaryToASCIIBuffer
119: 1 72 sun.util.locale.provider.JRELocaleProviderAdapter
120: 1 64 [F
121: 2 64 [Ljava.lang.Thread;
122: 2 64 java.io.FileOutputStream
123: 2 64 java.io.FilePermission
124: 2 64 java.io.PrintStream
125: 2 64 java.lang.ClassValue$Entry
126: 2 64 java.lang.VirtualMachineError
127: 2 64 java.lang.ref.ReferenceQueue$Null
128: 2 64 java.security.BasicPermissionCollection
129: 2 64 java.security.Permissions
130: 4 64 java.util.HashSet
131: 2 64 java.util.ResourceBundle$LoaderReference
132: 2 48 java.io.BufferedOutputStream
133: 1 48 java.io.BufferedReader
134: 2 48 java.io.File$PathStatus
135: 2 48 java.io.FilePermissionCollection
136: 2 48 java.io.OutputStreamWriter
137: 2 48 java.net.InetAddress$Cache
138: 2 48 java.net.InetAddress$Cache$Type
139: 1 48 java.net.SocketInputStream
140: 1 48 java.nio.HeapCharBuffer
141: 2 48 java.nio.charset.CoderResult
142: 3 48 java.nio.charset.CodingErrorAction
143: 2 48 sun.misc.NativeSignalHandler
144: 2 48 sun.misc.Signal
145: 2 48 sun.misc.URLClassPath$FileLoader
146: 3 48 sun.net.www.protocol.jar.Handler
147: 1 48 sun.nio.cs.StreamDecoder
148: 1 48 sun.nio.cs.US_ASCII$Decoder
149: 1 48 sun.util.locale.provider.LocaleResources$ResourceReference
150: 1 40 [Lsun.util.locale.provider.LocaleProviderAdapter$Type;
151: 1 40 java.io.BufferedInputStream
152: 1 40 java.util.ResourceBundle$1
153: 1 40 sun.nio.cs.StandardCharsets$Aliases
154: 1 40 sun.nio.cs.StandardCharsets$Cache
155: 1 40 sun.nio.cs.StandardCharsets$Classes
156: 1 40 sun.nio.cs.ext.ExtendedCharsets
157: 1 32 [Ljava.lang.OutOfMemoryError;
158: 2 32 [Ljava.lang.StackTraceElement;
159: 1 32 [Ljava.lang.ThreadGroup;
160: 1 32 [Ljava.net.Proxy$Type;
161: 1 32 java.io.WinNTFileSystem
162: 1 32 java.lang.ArithmeticException
163: 2 32 java.lang.Boolean
164: 1 32 java.lang.NullPointerException
165: 1 32 java.net.InetAddress$InetAddressHolder
166: 1 32 java.net.Socket
167: 2 32 java.nio.ByteOrder
168: 2 32 java.util.concurrent.atomic.AtomicInteger
169: 1 32 java.util.concurrent.atomic.AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl
170: 1 32 sun.instrument.InstrumentationImpl
171: 1 32 sun.nio.cs.StandardCharsets
172: 1 32 sun.util.locale.provider.LocaleResources
173: 1 32 sun.util.locale.provider.LocaleServiceProviderPool
174: 1 24 [Ljava.io.File$PathStatus;
175: 1 24 [Ljava.lang.ClassValue$Entry;
176: 1 24 [Ljava.net.InetAddress$Cache$Type;
177: 1 24 [Ljava.security.ProtectionDomain;
178: 1 24 [Lsun.launcher.LauncherHelper;
179: 1 24 java.io.InputStreamReader
180: 1 24 java.lang.ClassValue$Version
181: 1 24 java.lang.StringBuilder
182: 1 24 java.lang.invoke.MethodHandleImpl$4
183: 1 24 java.lang.reflect.ReflectPermission
184: 1 24 java.net.Inet4Address
185: 1 24 java.net.Inet6AddressImpl
186: 1 24 java.net.Proxy
187: 1 24 java.util.BitSet
188: 1 24 java.util.Collections$EmptyMap
189: 1 24 java.util.Collections$SetFromMap
190: 1 24 java.util.Locale$Cache
191: 1 24 java.util.ResourceBundle$Control$CandidateListCache
192: 1 24 sun.instrument.TransformerManager
193: 1 24 sun.launcher.LauncherHelper
194: 1 24 sun.misc.JarIndex
195: 1 24 sun.nio.cs.ISO_8859_1
196: 1 24 sun.nio.cs.ThreadLocalCoders$1
197: 1 24 sun.nio.cs.ThreadLocalCoders$2
198: 1 24 sun.nio.cs.US_ASCII
199: 1 24 sun.nio.cs.UTF_16
200: 1 24 sun.nio.cs.UTF_16BE
201: 1 24 sun.nio.cs.UTF_16LE
202: 1 24 sun.nio.cs.UTF_8
203: 1 24 sun.util.locale.BaseLocale$Cache
204: 1 24 sun.util.locale.provider.TimeZoneNameProviderImpl
205: 1 16 [Ljava.lang.Throwable;
206: 1 16 [Ljava.security.cert.Certificate;
207: 1 16 [Lsun.instrument.TransformerManager$TransformerInfo;
208: 1 16 java.io.FileDescriptor$1
209: 1 16 java.lang.CharacterDataLatin1
210: 1 16 java.lang.ClassValue$Identity
211: 1 16 java.lang.Runtime
212: 1 16 java.lang.String$CaseInsensitiveComparator
213: 1 16 java.lang.System$2
214: 1 16 java.lang.Terminator$1
215: 1 16 java.lang.invoke.MemberName$Factory
216: 1 16 java.lang.invoke.MethodHandleImpl$2
217: 1 16 java.lang.invoke.MethodHandleImpl$3
218: 1 16 java.lang.ref.Reference$1
219: 1 16 java.lang.ref.Reference$Lock
220: 1 16 java.lang.reflect.ReflectAccess
221: 1 16 java.net.InetAddress$2
222: 1 16 java.net.URLClassLoader$7
223: 1 16 java.nio.Bits$1
224: 1 16 java.nio.charset.CoderResult$1
225: 1 16 java.nio.charset.CoderResult$2
226: 1 16 java.security.ProtectionDomain$2
227: 1 16 java.security.ProtectionDomain$JavaSecurityAccessImpl
228: 1 16 java.util.Collections$EmptyIterator
229: 1 16 java.util.Collections$EmptyList
230: 1 16 java.util.Collections$EmptySet
231: 1 16 java.util.Hashtable$EntrySet
232: 1 16 java.util.ResourceBundle$Control
233: 1 16 java.util.WeakHashMap$KeySet
234: 1 16 java.util.jar.JavaUtilJarAccessImpl
235: 1 16 java.util.zip.ZipFile$1
236: 1 16 sun.misc.ASCIICaseInsensitiveComparator
237: 1 16 sun.misc.FloatingDecimal$1
238: 1 16 sun.misc.Launcher
239: 1 16 sun.misc.Launcher$Factory
240: 1 16 sun.misc.Perf
241: 1 16 sun.misc.Unsafe
242: 1 16 sun.net.spi.DefaultProxySelector
243: 1 16 sun.net.www.protocol.file.Handler
244: 1 16 sun.reflect.ReflectionFactory
245: 1 16 sun.util.calendar.Gregorian
246: 1 16 sun.util.locale.provider.AuxLocaleProviderAdapter$NullProvider
247: 1 16 sun.util.locale.provider.SPILocaleProviderAdapter
248: 1 16 sun.util.locale.provider.TimeZoneNameUtility$TimeZoneNameGetter
249: 1 16 sun.util.resources.LocaleData
250: 1 16 sun.util.resources.LocaleData$LocaleDataResourceBundleControl
Total 16750 1270808
3)jmap -dump ,format = b file = heap.tdump pid
打印整个堆快照,这个命令执行,
JVM会将整个heap的信息dump写入到一个文件,
heap如果比较大的话,就会导致这个过程比较耗时。执行的过程中为了保证dump的信息是可靠的,所以会暂停应用(STW),进行FULL GC。所以建议如果不是很有必要的话,不要去执行。format = b 是表打印二进制文件,
-live, 此事只统计活的对象数量.
jmap -dump ,format = b file = heap.tdump pid
jmap -dump:live,format=b,file=heap.tdump
A、打印堆快照的其他方式
虚拟机启动时如果指定了 -XX:+HeapDumpOnOutOfMemoryError 选项, 则在抛出 OutOfMemoryError 时, 会自动执行堆转储
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path
B、jhat 工具分析
这个文件使用工具进行分析,这个非常关键,具体分析,看后面的内容
$ jmap -dump:format=b,file=333.tdump 12316
Dumping heap to D:\programFiles\java-1.8.0-openjdk\bin\333.tdump ...
Heap dump file created

6、jhat :
浏览器分析dump文件
1)jhat -J-Xmx1024m D:/javaDump.tdump
浏览器分析dump文件,说明: -J是向java虚拟机传一个参数,如-Xmx768m是指定虚拟机可用最大的内存为768M。如果映像文件很大,你要指定一个很大的值,否则在分析过程中就会有OutOfMemeryError的错误。
1、jhat是一个Java堆复制浏览器。这个工具分析Java堆复制文件(
jmap -dump出来的 heap文件. )。jhat 命令解析Java堆转储文件,并启动一个 web server. 然后用浏览器来查看/浏览使用名 `2、jhat 命令支持预先设计的查询, 比如显示某个类的所有实例. 还支持 对象查询语言(OQL, Object Query Language)。 OQL有点类似SQL,专门用来查询堆转储。 OQL相关的帮助信息可以在 jhat 命令所提供的服务器页面最底部. 如果使用默认端口, 则OQL帮助信息页面为: http://localhost:7000/oqlhelp/
$ jhat -J-Xmx1024m 333.tdump
Reading from 333.tdump...
Dump file created Wed Jan 08 10:39:57 CST 2020
Snapshot read, resolving...
Resolving 55284 objects...
Chasing references, expect 11 dots...........
Eliminating duplicate references...........
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.

2)开始分析浏览器中的dump文件
A、显示出堆中所包含的所有的类
http://localhost:7000/allClassesWithPlatform/

B、从根集能引用到的对象

C、显示平台包括的所有类的实例数量

D、堆实例的分布表

E、执行对象查询语句

jhat中的OQL(对象查询语言)
如果需要根据某些条件来过滤或查询堆的对象,这是可能的,可以在jhat的html页面中执行OQL,来查询符合条件的对象
基本语法:
select <javascript expression to select>
[from [instanceof] <class name> <identifier>]
[where <javascript boolean expression to filter>]
解释:
(1)class name是java类的完全限定名,如:java.lang.String, java.util.ArrayList, [C是char数组, [Ljava.io.File是java.io.File[]
(2)类的完全限定名不足以唯一的辨识一个类,因为不同的ClassLoader载入的相同的类,它们在jvm中是不同类型的
(3)instanceof表示也查询某一个类的子类,如果不明确instanceof,则只精确查询class name指定的类
(4)from和where子句都是可选的
(5)java域表示:obj.field_name;java数组表示:array[index]
举例:
(1)查询长度大于100的字符串
select s from java.lang.String s where s.count > 100
(2)查询长度大于256的数组
select a from [I a where a.length > 256
(3)显示匹配某一正则表达式的字符串
select a.value.toString() from java.lang.String s where /java/(s.value.toString())
(4)显示所有文件对象的文件路径
select file.path.value.toString() from java.io.File file
(5)显示所有ClassLoader的类名
select classof(cl).name from instanceof java.lang.ClassLoader cl
(6)通过引用查询对象
select o from instanceof 0xd404d404 o
built-in对象 -- heap
(1)heap.findClass(class name) -- 找到类
select heap.findClass("java.lang.String").superclass
(2)heap.findObject(object id) -- 找到对象
select heap.findObject("0xd404d404")
(3)heap.classes -- 所有类的枚举
select heap.classes
(4)heap.objects -- 所有对象的枚举
select heap.objects("java.lang.String")
(5)heap.finalizables -- 等待垃圾收集的java对象的枚举
(6)heap.livepaths -- 某一对象存活路径
select heaplivepaths(s) from java.lang.String s
(7)heap.roots -- 堆根集的枚举
辨识对象的函数
(1)classof(class name) -- 返回java对象的类对象
select classof(cl).name from instanceof java.lang.ClassLoader cl
(2)identical(object1,object2) -- 返回是否两个对象是同一个实例
select identical(heap.findClass("java.lang.String").name, heap.findClass("java.lang.String").name)
(3)objectid(object) -- 返回对象的id
select objectid(s) from java.lang.String s
(4)reachables -- 返回可从对象可到达的对象
select reachables(p) from java.util.Properties p -- 查询从Properties对象可到达的对象
select reachables(u, "java.net.URL.handler") from java.net.URL u -- 查询从URL对象可到达的对象,但不包括从URL.handler可到达的对象
(5)referrers(object) -- 返回引用某一对象的对象
select referrers(s) from java.lang.String s where s.count > 100
(6)referees(object) -- 返回某一对象引用的对象
select referees(s) from java.lang.String s where s.count > 100
(7)refers(object1,object2) -- 返回是否第一个对象引用第二个对象
select refers(heap.findObject("0xd4d4d4d4"),heap.findObject("0xe4e4e4e4"))
(8)root(object) -- 返回是否对象是根集的成员
select root(heap.findObject("0xd4d4d4d4"))
(9)sizeof(object) -- 返回对象的大小
select sizeof(o) from [I o
(10)toHtml(object) -- 返回对象的html格式
select "<b>" + toHtml(o) + "</b>" from java.lang.Object o
(11)选择多值
select {name:t.name?t.name.toString():"null",thread:t} from instanceof java.lang.Thread t
数组、迭代器等函数
(1)concat(enumeration1,enumeration2) -- 将数组或枚举进行连接
select concat(referrers(p),referrers(p)) from java.util.Properties p
(2)contains(array, expression) -- 数组中元素是否满足某表达式
select p from java.util.Properties where contains(referres(p), "classof(it).name == 'java.lang.Class'")
返回由java.lang.Class引用的java.util.Properties对象
built-in变量
it -- 当前的迭代元素
index -- 当前迭代元素的索引
array -- 被迭代的数组
(3)count(array, expression) -- 满足某一条件的元素的数量
select count(heap.classes(), "/java.io./(it.name)")
(4)filter(array, expression) -- 过滤出满足某一条件的元素
select filter(heap.classes(), "/java.io./(it.name)")
(5)length(array) -- 返回数组长度
select length(heap.classes())
(6)map(array,expression) -- 根据表达式对数组中的元素进行转换映射
select map(heap.classes(),"index + '-->' + toHtml(it)")
(7)max(array,expression) -- 最大值, min(array,expression)
select max(heap.objects("java.lang.String"),"lhs.count>rhs.count")
built-in变量
lhs -- 左边元素
rhs -- 右边元素
(8)sort(array,expression) -- 排序
select sort(heap.objects('[C'),'sizeof(lhs)-sizeof(rhs)')
(9)sum(array,expression) -- 求和
select sum(heap.objects('[C'),'sizeof(it)')
(10)toArray(array) -- 返回数组
(11)unique(array) -- 唯一化数组
二、Jprofiler
1、类

2、最大对象

3、引用
1)传入引用
传入引用 指的是从其他对象指向当前分析对象的引用。这些引用是外部对象对当前对象的“知晓”或“持有”的方式。在
JProfiler中,当你查看一个对象的详细信息时,传入引用列表会显示所有指向该对象的外部引用。这些引用是理解对象如何被其他部分代码使用或依赖的关键。

2)合并的传入引用
合并的传入引用是
JProfiler为了简化视图而提供的一个功能。当存在多个相同的传入引用(即多个外部对象通过相同的引用类型指向当前对象)时,这些引用可能会被合并显示。这样做可以减少视图中的冗余,使得分析更加集中和高效。合并的传入引用通常显示为一个总数,旁边可能还会有一个展开按钮,允许你查看具体的引用详情。

3)传出引用
传出引用与传入引用相反,它指的是从当前分析对象指向其他对象的引用。这些引用表示当前对象如何“知晓”或“持有”其他对象。在
JProfiler中,查看一个对象的传出引用可以帮助你理解该对象如何与其他对象交互,以及它可能如何影响这些对象的生命周期。

4)合并的传出引用
合并的传出引用与合并的传入引用类似,是
JProfiler为了简化视图而提供的功能。当当前对象有多个指向相同类型或相同实例的传出引用时,这些引用可能会被合并显示。这有助于减少视图中的噪声,让你更容易地识别出主要的引用模式和依赖关系。

4、其他
1)内存大小
a、 JProfiler 的保留大小
-
定义:在
JProfiler的内存分析视图中,保留大小(Retained Size)指的是如果一个对象及其所有可达对象(即该对象通过引用链可以访问到的所有对象)被垃圾回收(GC)所释放的内存总量。这个大小反映了该对象及其相关对象在内存中占用的空间。 -
用途:保留大小是识别内存泄漏和性能瓶颈的关键指标。通过
JProfiler,开发者可以轻松地查看哪些对象占用了大量内存,并据此进行优化。
b、JVM 实际占用内存
-
定义:
JVM实际占用内存指的是JVM在运行时为其堆(Heap)、方法区(Metaspace,JDK 8及以后版本中的永久代替代品)、栈(Stack)等内存区域分配并实际使用的内存总量。这些内存区域的大小可以通过JVM的启动参数(如-Xmx、-Xms、-Xss等)进行设置和调整。 -
动态性:
JVM实际占用内存是动态变化的,它随着应用程序的运行状态和内存使用情况而不断变化。
c、二者关系
-
相互关联:
JProfiler的保留大小是JVM实际占用内存的一个子集,它反映了JVM内存中特定对象及其可达对象所占用的空间。通过JProfiler的内存分析,开发者可以深入了解JVM内存中各个对象的保留大小,从而识别出内存占用较大的对象或数据结构,并据此进行优化。 -
并非等同:然而,需要注意的是,
JProfiler的保留大小并不等同于JVM的实际占用内存。JVM的实际占用内存包括了堆内存、方法区、栈内存等多个部分,而保留大小只是针对特定对象及其可达对象而言的。此外,JVM的实际占用内存还可能受到操作系统、JVM实现、垃圾回收算法等多种因素的影响。


