前言
java -Xms4G -Xmx4G -XX:MaxMetaspaceSize=512m -XX:MetaspaceSize=512m -XX:MaxDirectMemorySize=256m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./<pid>.hprof -Dfile.encoding=UTF-8 -jar demo.jar
上面是典型的启动 Java 程序时会携带的参数,你能讲清它们每个参数的作用吗?
JVM 参数
JVM 参数很多,但实际有用的并不多。参数全列出来意义不大,毕竟我自己都不想看。下面列出的都是常用的参数
基本参数
-X
后面的参数通常是一些标准的 JVM 选项,用于设置 JVM 的基本配置
-XX
后面的参数是 JVM 的内部参数,通常用于调优或控制一些更底层的细节。它们不是标准 Java 选项,因此有些选项可能在不同版本的 JVM 中有差异
参数 | 说明 | 建议 |
---|---|---|
-Xmx | 最大堆内存 | 容器内存的一半 |
-Xms | 初始堆内存 | 容器内存的一半 |
-XX:MaxMetaspaceSize | 最大元空间内存 | 256MB ~ 512MB |
-XX:MetaspaceSize | 初始元空间内存 | 256MB ~ 512MB |
其他参数
参数 | 说明 | 建议 |
---|---|---|
-XX:+HeapDumpOnOutOfMemoryError | 发生 OOM 时,生成 heap dump 文件 | 开启 |
-XX:HeapDumpPath | heap dump 文件存储路径 | |
-XX:+PrintGCDetails | 打印垃圾回收的详细信息 |
ParallelGC
适用于需要较高吞吐量、对 GC 停顿不敏感的应用
参数 | 说明 | 建议 |
---|---|---|
-XX:+UseParallelGC | 启用 ParallelGC | JDK8 默认 |
-XX:ParallelGCThreads | 并行 GC 线程数 | 容器 CPU 核心数 |
假设是 4c8g 的机器,可以这样写:
java -Xms4g -Xmx4g -XX:+UseParallelGC -XX:ParallelGCThreads=4 -jar your-application.jar
CMS
适合需要低延迟,且对停顿时间较为敏感的应用,但在 JDK 9 之后已不推荐使用
参数 | 说明 | 建议 |
---|---|---|
-XX:+UseConcMarkSweepGC | 启用 CMS | |
-XX:+UseCMSInitiatingOccupancyOnly | 使用设定的回收阈值 | |
-XX:CMSInitiatingOccupancyFraction | 设置 GC 回收阈值 | 70 |
java -Xms4g -Xmx4g -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSInitiatingOccupancyOnly -jar your-application.jar
G1
适合大内存、低延迟应用,尤其是当有对停顿时间有明确要求时
参数 | 说明 | 建议 |
---|---|---|
-XX:+UseG1GC | 启用 G1 | JDK17 默认 |
-XX:G1HeapRegionSize | region 大小 | 8MB |
java -Xms4g -Xmx4g -XX:+UseG1GC -XX:G1HeapRegionSize=8m -jar your-application.jar
ZGC
适用于超大内存的高效低延迟应用,特别是在需要减少 GC 停顿的情况下
(ZGC 一般不用怎么调参数)
参数 | 说明 | 建议 |
---|---|---|
-XX:+UseZGC | 启用 ZGC |
java -Xms4g -Xmx4g -XX:+UseZGC -jar your-application.jar
其他问题
JVM 调优?
JVM 几乎不需要调优,监控远比调优重要,比如使用 Prometheus+Grafana。出现了线上问题,大概率是我们的代码写的有问题,而不是 JVM 自身的问题
我们限制堆内存、元空间内存上限是为了防止内存过度消耗,避免触发 swap 影响性能或影响到其它的内存区域
当遇到以下问题时,才考虑是否要 JVM 调优:
- FullGC 频繁
- GC 停顿时间长
- OOM
所谓“调优”也无非是调调年轻代内存大小,老年代内存大小罢了。实际都不如继续加物理内存管用
出现内存泄漏需要调优吗?
内存泄漏说明代码有问题,跟 JVM 没什么关系。继续调大堆内存,也只是让内存泄漏导致的内存溢出的时间延后而已
最佳实践?
- 加内存到 8G 以上
- -Xmx -Xms 设置堆内存大小
- 使用 JDK17 或 JDK21,用 G1 或 ZGC
java -Xms4g -Xmx4g -XX:+UseG1GC -XX:G1HeapRegionSize=8m -jar your-application.jar
结语
如果大家感觉有帮助,欢迎点赞收藏+关注,有问题可以在评论区评论哦!
公众号【牛肉烧烤屋】
B 站【爱烤猪蹄的乔治】
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。