一、启动参数概览
JVM 的启动参数, 从形式上可以简单分为:
-
以
-
开头为标准参数,所有的 JVM 都要实现这些参数,并且向后兼容。通过
java -help
命令来检索出所有标准参数。 -
以
-X
开头为非标准参数, 基本都是传给 JVM 的,默认 JVM 实现这些参数的功能,但是并不保证所有 JVM 实现都满足,且不保证向后兼容。通过
java -X
命令来检索所有-X
参数 -
以
-XX:
开头为非稳定参数, 专门用于控制 JVM 的行为,跟具体的 JVM 实现有关,随时可能会在下个版本取消。-XX:+-Flags
形式, ± 是对布尔值进行开关。-XX:key=value
形式, 指定某个选项的值。
通过
java -XX:+PrintFlagsFinal -version
来检索所有-XX:
参数; -
-D
参数用于设置系统属性,可以在应用程序中使用System.getProperty
方法获取;通过
jcmd <pid> VM.system_properties
或者jinfo -syspros <pid>
来检索所有系统属性;举例:设置系统加载器路径和扩展类加载器路径:
-Dsun.boot.class.path
=“D:\Program Files\Java\jre1.8.0_231\lib\rt.jar”-Djava.ext.dirs
=/path
二、启动参数全貌
基于 java version “21.0.4” 2024-07-16 LTS
2.1 标准参数 ( -
)
2.2 非标准参数 ( -X
)
2.3 非稳定参数 ( -XX:
)
2.4 系统属性 ( -D
)
三、常用参数
3.1 打印已经被用户或者当前虚拟机设置过的参数
通过 -XX:+PrintCommandLineFlags
参数让JVM打印出那些已经被用户或者JVM设置过的详细的XX参数的名称和值。
它列举出 -XX:+PrintFlagsFinal
的结果中第三列有":=
"的参数。
3.2 jvm启动配置参数
-
-Xms4096M
设置Java堆内存初始值为4096M,(ms是memory start)
-
-Xmx4096M
设置Java堆内存最大值为4096M,(mx是memory max)
-
-Xmn1024M
设置新生代堆内存最大值为1024M,(mn是memory new)
-
-Xss1M
设置每个线程的堆栈大小为1M
-
-XX:NewSize=256M -XX:MaxNewSize=1024M
设置新生代堆内存为256M, 最大为1024M,另外一种方式而已
-
-XX:NewRatio=2
设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。设置为2,则年轻代与年老代所占比值为1:2,年轻代占整个堆栈的1/3
-
-XX:SurvivorRatio=8
设置年轻代中Eden区与Survivor区的大小比值。设置为8,则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10
-
-XX:+UseSerialGC
启用串行GC
-
-XX:MaxGCPauseMillis=200
设置新生代每次垃圾回收的最长时间,如果无法满足此时间,JVM会自动调整新生代大小,以满足此值。
-
-XX:ParallelGCThreads=20
配置并行收集器的线程数为20
-
-XX:+UseParallelGC
设置新生代垃圾收集器为:并行收集器
同时运行在多个cpu之间,最大化的提高程序吞吐量,缩短程序停顿时间
不能配合老年代的 CMS 使用;
jdk1.7选择 parallel 回收器默认开启的。
-
-XX:+UseParallelOldGC
设置老年代垃圾收集器为:并行收集器
当
-XX:+UseParallelGC
启用时该项自动启用 -
-XX:+UseConcMarkSweepGC
设置老年代垃圾收集器为:并发收集器(CMS)
只能搭配新生代Serial(串行)、ParNew(并发)收集器
-
-XX:+UseParNewGC
设置新生代垃圾收集器为:并发串行收集器
将串行收集器多线程化,收集过程中,应用程序会全部暂停;
可以配合老年代的 CMS 使用;
-
-XX:+PrintGC
打印GC简要信息;
-
-XX:+PrintGCDetails
打印GC详细信息;
-
-XX:+PrintGCTimeStamps
打印GC时间戳;
-
-Xloggc:filename
将GC日志输出到文件filename;
-
-XX:MetaspaceSize=512M -XX:MaxMetaspaceSize=512M
设置Metaspace(元空间)大小;JDK 1.8 开始,用来替换原来的永久代(-XX:MaxPermSize=512m)
方法区:
《Java 虚拟机规范》定义了方法区概念和作用,并没有规定如何去实现它;永久代、元空间: 均是HotSpot 虚拟机对虚拟机规范中方法区的一种实现方式;
- 永久代:使用JVM内存,受制于JVM 本身设置的固定大小上限,无法进行调整;
- 元空间:使用直接内存,受本机可用内存的限制;默认值为 unlimited,这意味着它只受系统内存的限制;溢出概率低于永久代。
-
-XX:TargetSurvivorRatio
设置Survivor区目标使用比例(触发动态年龄判断的阈值) 50%
-
-XX:MaxTenuringThreshold=15
设置晋升老年代年龄阈值;
Hotspot 遍历所有对象时,按照年龄从小到大对其所占用的大小进行累积,当累积的某个年龄大小超过了 survivor 区的
50%
时,取这个年龄和 MaxTenuringThreshold 中更小的一个值,作为新的晋升年龄阈值 -
-XX:HeapDumpPath=./java_pid.hprof
指定导出堆信息时的路径或文件名
-
-XX:+HeapDumpOnOutOfMemoryError
当首次遭遇OOM时导出此时堆中相关信息
-
-XX:+TraceClassLoading
跟踪类的加载信息
-
-XX:OnOutOfMemoryError=elf.script
表示发生OOM后,执行脚本,比如发送邮件告警信息、用来重启系统等;
-
-XX:PretenureSizeThreshold
设置直接分配大对象到老年代的阈值。如果对象的大小超过这个阈值,它将直接在老年代中分配;
分配单位为字节,如-XX:PretenureSizeThreshold=5242880,5MB(510241024)
3.3 调试参数
- 类加载卸载日志
# OpenJDK 8及以下版本
-XX:+TraceClassLoading
-XX:+TraceClassUnloading
# OpenJDK 9+ 版本(需使用新的日志框架)
-Xlog:class+load=info
-Xlog:class+unload=info
四、JVM性能调优工具
4.1 java 自带工具
-
jps(Java Process Status):输出JVM中运行的进程状态信息(现在一般使用jconsole)
常用选项:
- -q 只输出进程 ID,忽略主类信息;
- -l 输出主类全名,或者执行 JAR 包则输出路径;
- -m 输出虚拟机进程启动时传递给主类 main() 方法的参数;
- -v 输出虚拟机进程启动时的 JVM 参数;
-
jstack:查看java进行内线程的堆栈信息。
-
jmap:用于生成堆转存快照,如命令
jmap -histo:live,file=/tmp/histo.data <pid>
-
jstat:JVM统计监测工具。可以用来显示垃圾回收信息、类加载信息、新生代统计信息等。
常用选项:
-class
监视类加载、卸载数量、总空间以及类装载所耗费时长
- -gc 监视 Java 堆情况,比如容量、已用空间、垃圾收集时间合计等信息
- -gccapacity 监视内容与-gc 基本一致,但输出主要关注 Java 堆各个区域使用到的最大、最小空间
- -gcutil 监视内容与-gc 基本相同,但输出主要关注已使用空间占总空间的百分比
- -gccause 与 -gcutil 功能一样,但是会额外输出导致上一次垃圾收集产生的原因
- -gcnew 监视新生代垃圾收集情况
- -gcold 监视老年代垃圾收集情况
- -gcnewcapacity 监视内容与 -gcnew 基本相同,输出主要关注使用到的最大、最小空间
- -gcoldcapacity 监视内容与 -gcold 基本相同,输出主要关注使用到的最大、最小空间
- -compiler 输出即时编译器编译过的方法、耗时等信息
-
jinfo:输出 Java 进程的详细信息
常用选项:
- -flags 打印虚拟机参数
-
VisualVM:故障处理工具
-
jcmd:JDK 7+ 提供的多功能诊断工具,可替代 jps、jstack、jmap 等传统命令,并支持动态交互与高级监控(如 JFR, Java Flight Recorder,Java 性能分析工具,java “黑匣子”)
命令 | 作用 | 示例 |
---|---|---|
jcmd -l | 列出所有Java进程(同 jps -lm) | jcmd -l |
jcmd help | 查看目标进程支持的子命令列表 | jcmd 1234 help |
jcmd VM.version | 显示JVM版本信息 | jcmd 1234 VM.version |
jcmd Thread.print | 打印线程堆栈(替代 jstack) | jcmd 1234 Thread.print |
jcmd GC.heap_dump | 生成堆转储文件(替代 jmap -dump) | jcmd 1234 GC.heap_dump /path/dump.hprof |
jcmd GC.class_histogram | 显示类实例统计(类似 jmap -histo) | jcmd 1234 GC.class_histogram |
jcmd VM.native_memory | 分析堆外内存(需开启 -XX:NativeMemoryTracking=detail) | jcmd 1234 VM.native_memory detail |
jcmd VM.system_properties | 输出所有系统属性(同 jinfo -sysprops) | jcmd 1234 VM.system_properties |
jcmd VM.flags | 查看JVM启动参数 | jcmd 1234 VM.flags |
jcmd PerfCounter.print | 打印性能计数器数据 | jcmd 1234 PerfCounter.print |
jcmd JFR.start | 启动性能记录(需解锁商业特性) | jcmd 1234 JFR.start name=profile duration=60s filename=recording.jfr |
jcmd JFR.dump | 导出JFR记录文件 | jcmd 1234 JFR.dump name=profile filename=recording.jfr |
jcmd JFR.stop | 停止记录 | jcmd 1234 JFR.stop name=profile |