发布时间:2025-11-10
浏览次数:0
JVM参数分类1️⃣ 标准参数(-)
稳定,所有 JVM 版本都支持
-version
-help
-classpath
-Dproperty=value
2️⃣ 非标准参数(-X)
不保证所有 JVM 都支持,但实际上都支持
-Xms512m
-Xmx2g
-Xss256k
-Xmn1g
3️⃣ 不稳定参数(-XX)
实验性质,可能会变化
-XX:+UseG1GC
-XX:-UseParallelGC
-XX:MaxGCPauseMillis=200
核心参数详解一、堆内存设置 ️基本参数
-Xms4g
-Xmx4g
关键原则 :-Xms 和 -Xmx 设置成一样大!
为什么?
如果不一样:
启动时:堆大小 2GB
于运行的过程当中,出现了内存不足的情形,进而将其扩大容量至4GB,此操作引发了Full GC,最终导致出现卡顿 !
如果一样:
启动时:堆大小 4GB
运行中:不需要扩容,稳定运行
生活比喻 :
堆内存设置多大合适?
经验公式:
开发环境:-Xms512m -Xmx512m
测试环境:-Xms2g -Xmx2g
生产环境之中,存在这样的情况,即 -Xms 等于 -Xmx ,其数值为 物理内存 乘以 70% 到 80% ,举例来说,对于 8GB 内存的机器 ,就会是 -Xms6g , -Xmx6g ,而对于 16GB 内存的机器 ,则是 -Xms12g , -Xmx12g ,那么为什么不是 100% 呢?原因在于 操作系统 需要内存 , 堆外内存,也就是 DirectByteBuffer 需要内存 , JVM 自身也需要内存 。
新生代 vs 老年代
堆内存划分:
┌─────────────────────────────────┐,│堆内存,Heap这一部分,│,│ │,┌─────────────────┐,│ │,│新生代,Young Gen这一部分,其占用占比为1/3,│ │,│ │ │ │伊甸区,Eden加上,│ │ │ │ │ │ ┌─────────────────┐ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │.
│ └─────────────────┘ │,│ │ │ │,┌─────────────────┐ │,│ │OLD Gen │ │,│ │(老年代 2/3) │ │,│ │ │ │,└─────────────────┘ │,└─────────────────────────────────┘ 。
参数控制 :
-Xmn2g
-XX:NewRatio=2
不设置 -Xmn,让 GC 自适应
推荐 :
二、垃圾回收器选择 ️GC 选择对照表
你提供的内容并非完整句子,请提供完整的句子以便我按照要求进行改写。
|GC|存在-XX:+的情况,针对单核CPU、客户端,呈现长以及高的特性,|GC|存在-XX:+的情况,针对多核CPU、侧重于吞吐量优先,呈现中以及最高的特性,|CMS|存在-XX:+的情况,针对低延迟、旧版本,呈现短以及中的特性,|G1 GC|存在-XX:+的情况,针对大堆、较为均衡,呈现短以及高的特性codejock xtreme toolkit,|ZGC|存在-XX:+的情况,针对超大堆、具备极低延迟,呈现极短以及高的特性,|存在-XX:+的情况,针对超大堆、具备极低延迟,呈现极短以及高的特性。
推荐方案
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:G1HeapRegionSize=16m
-XX:G1ReservePercent=10
减XX:启动堆占用百分比等于45 。句号不能少,不然不符合句子要求。
减XX,加UseParallelGC,减XX,设ParallelGCThreads等于8,减XX,设MaxGCPauseMillis等于500,减XX,设GCTimeRatio等于99 。
减去XX,加上UseZGC,减去XX,设置ZCollectionInterval为此120,减去XX,设置ZAllocationSpikeTolerance为5,。
G1 GC 详解(重点)
G1的核心思想是,将堆进行切分,切分成2048个部分,并且优先对垃圾最多的部分实施回收, 。
堆内存(4GB):
G1 的优势 :
G1 最佳实践 :
-Xms8g -Xmx8g
-XX:+UseG1GC
-XX ,其值为 MaxGCPauseMillis 且等于是 200 ,同时别忘另有 -XX ,其值为 MaxGCPauseMillis 且等于是 500 。
-XX:G1HeapRegionSize=16m
-XX:ConcGCThreads=2
减掉XX,加上ParallelRefProcEnabled,再减掉XX,加上DisableExplicitGC 。
C 三、GC 日志配置
为什么要开启 GC 日志?
JDK 8 的GC日志配置
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+PrintGCTimeStamps
-Xloggc:/var/log/gc.log
设置为不使用XX,启用使用垃圾回收日志文件轮转,设置垃圾回收日志文件数量为五,设置每个垃圾回收日志文件大小为二十兆 。
-XX,加上HeapDumpOnOutOfMemoryError,-XX,HeapDumpPath设定为/var/log/heapdump.hprof 。
JDK 9+ 的GC日志配置(统一日志)
减X日志:垃圾回收相关内容:日志存放至路径=/var/log/gc.log下:记录时间、级别、标签等内容:保存此类日志的文件个数=5个,文件总大小=20兆字节。
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/log/heapdump.hprof
四、线程相关参数
-Xss256k
栈大小设置建议 :
C 五、元空间()️
JDK 8 之后,永久代()被元空间()取代
-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=512m
-XX ,初始引导类加载器元空间大小等于 64 兆字节 。
元空间 vs 永久代 :
| 特性 | 永久代() | 元空间() | | ---
设有位置,其包含堆内存与本地内存,堆内存默认大小为64MB且此大小过小,本地内存无限制且更为灵活,堆内存存在OOM风险且容易引发OOM,本地内存不容易引发OOM,堆内存需Full GC才进行回收,本地内存会自动进行回收。
什么时候会用满元空间?
完整的JVM参数模板模板 1:通用 Web 应用(推荐)
#!/bin/bash
APP_NAME="my-web-app"
JAVA_OPTS="
# ===== 堆内存配置 =====
-Xms4g -Xmx4g -Xss256k
# ===== GC 配置(G1) =====
将“-XX:+UseG1GC”改为“-XX 加上 UseG1GC”,“-XX:MaxGCPauseMillis=200”改为“-XX 后面跟着冒号,MaxGCPauseMillis 等于 200”,“-XX:G1HeapRegionSize=16m”改为“-XX 后面跟着冒号,G1HeapRegionSize 等于 16m”,“-XX:InitiatingHeapOccupancyPercent=45”改为“-XX 后面跟着冒号,Initiating。
# ===== 元空间配置 =====
零下XX,元空间大小等于256兆字节,零下XX,最大元空间大小等于512兆字节。
# ===== GC 日志配置 =====
给-Xlog添加gc相关的日志记录,日志文件路径为文件系统中/var/log/下,以${APP_NAME}为名称的文件夹内的gc.log文件,记录时间、级别、标签等信息,日志文件数量上限为10个,每个文件大小上限为50M 。
# ===== OOM 时 Dump =====
在运行程序时,添加这样的参数设置,即,将-XX:+HeapDumpOnOutOfMemoryError添加进去,同时,把-XX:HeapDumpPath设置为/var/log/${APP_NAME}/heapdump.hprof 。
# ===== 其他优化 =====
-XX ,要加上 :DisableExplicitGC ,以此来禁用 System.gc() 。
减去XX,加上并行处理引用所启用的状态 # 并行处理引用。
-Djava.awt.headless 被设置为 true ,这是用于无 GUI 环境相关设置 。
-Dfile.encoding=UTF-8 # 文件编码
-用户的时区设定为亚洲上海,# 此乃对其时区相关内容的说明。 在此处,“-Duser.timezone”指向了特定的取值方位。
# ===== 远程调试(生产环境不要开启) =====
# 采用这样一种运行参数设置,其中 -agentlib 部分被设定为 jdwp,它有着特定参数,分别是 transport 被指定为 dt_socket,server 设置为 y,suspend 设置为 n,address 被设定为 5005。
"

用Java,借助那$JAVA_OPTS,去运行那个标注为${APP_NAME}.jar的文件 。
模板 2:高吞吐量批处理(离线任务)
JAVA_OPTS="
# 堆内存(尽量大)
-Xms16g -Xmx16g
# Parallel GC(吞吐量最高)
减去XX,加上使用并行垃圾回收器,设置并行垃圾回收线程数为8,设定最大垃圾回收停顿时间为1000毫秒,设置垃圾回收时间占比为99,# 垃圾回收时间占比 。< 1%
# 大对象直接进老年代
-XX:PretenureSizeThreshold=2m
# 元空间
减XX,元空间大小等于512兆字节,减XX,最大元空间大小等于1千兆字节 。
# GC 日志
-Xlog:gc*:file=/var/log/batch/gc.log:time,level,tags:filecount=5,filesize=100M
# OOM Dump
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/log/batch/heapdump.hprof "
C 模板 3:超低延迟服务(ZGC)
JAVA_OPTS="
# 堆内存(ZGC 适合大堆)
-Xms32g -Xmx32g
# 使用 ZGC(JDK 15+)
减XX加上使用ZGC,减XX中ZCollectionInterval设置为5妙,用于表述GC间隔时间为5秒 。
采用大页需操作系统予以支持,其相关参数设置为,-XX:ZAllocationSpikeTolerance=2,-XX:+UnlockExperimentalVMOptions,-XX:+UseLargePages 。
# 元空间
-XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=1g
# GC 日志
文件路径为 /var/log/low-latency/gc.log ,日志级别为 time、level、tags ,日志文件数量为10个,文件大小为50M ,记录的是 -Xlog:gc* 相关内容 。
# OOM Dump
减掉XX,添加HeapDumpOnOutOfMemoryError,将XX设定为HeapDumpPath,路径为/var/log/low-latency/;heapdump.hprof!
C 模板 4:容器化环境(/K8s)
JAVA_OPTS="
# 堆内存(容器内存的 75%)
减XX,初始随机存取存储器百分比等于七十五点零,减XX,最大随机存取存储器百分比等于七十五点零,减XX,最小随机存取存储器百分比等于五十点零 。
需要使用容器感知,其要求为JDK 8u191及以上版本,或者JDK 11及以上版本 。
-XX:+UseContainerSupport
# GC(G1)
将“-XX”标记为负该项,加上“+UseG1GC”设置,“-XX”后面跟着“:MaxGCPauseMillis=200。
# 其他
减XX半角冒号分隔号MetaspaceSize等号置于主从关系起始之128米,减XX半角冒号分隔号MaxMetaspaceSize等号置于主从关系终结之256米,减Xlog半角冒号分隔号gc星号半角冒号分隔号file等号置于主从关系起始之斜杠logs斜杠gc点日志半角冒号分隔号time级别标签半角冒号分隔号filecount等号置于主从关系起始之5,filesize等号置于主从关系终结之20米,减XX加HeapDumpOnOutOfMemoryError,减XX半角冒号分隔号HeapDumpPath等号及置于相对关系中心之斜杠logs斜杠heapdump点hprof引号。
容器化注意事项 :
调优实战案例C 案例1:频繁 Full GC
现象 :
每隔10分钟触发一次 Full GC,每次停顿 5 秒
应用卡顿,用户体验差
分析 GC 日志 :
【Full GC(因分配失败而触发)】 【PSYoungGen区域:从256K变为0K(总共256M范围)】 。
[旧代养老区:从1999兆字节变为2000兆字节(共2048兆字节)]。
1999M转变为2000M(2304M),用时5.1234567秒 。
发现问题 :
解决方案 :
用MAT对heap dump展开分析,从中找寻到内存泄漏点,进而修复内存泄漏,此内容可见于第227篇文档,还要适当增添堆内存,具体参数为 -Xms4g ,而后谈谈案例2,即Young GC时间历时过长 。
现象 :
Young GC 频繁,每次停顿 500ms 应用响应慢
分析 :
[通用收集(分配失败情况),][新一代并行幸存代空间:从占用512兆字节变为占用128兆字节(当前可用容量为512兆字节)]。
原本是512M,变为256M(这里是2048M对应的变化情况),用时0.5234567秒。
发现问题 :
解决方案 :
-Xmn1g
-XX:SurvivorRatio=8
-XX:MaxTenuringThreshold=15
C 案例3:
现象 :
在“main”线程中出现异常,具体为“java.lang.OutOfMemoryError”,错误类型是“Metaspace” 。
原因 :
解决方案 :
-XX:MetaspaceSize=512m
-XX:MaxMetaspaceSize=1g
调优效果对比优化前
-Xms512m -Xmx2g
新生代垃圾回收:每隔十秒钟就要进行一回,平均所消耗的时间为二百毫秒,老年代垃圾回收:每五分钟开展一次,平均耗费时间三秒,堆内存的使用比率:百分之八十五(常常近乎达到上限),应用响应时长:第九十九百分位数等于一千五百毫秒。
优化后
-Xms4g -Xmx4g
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
Young垃圾回收:每隔三十秒就会进行一次,其平均耗时为五十毫秒,Full垃圾回收:不存在这种情况!堆内存的使用率为百分之六十(处于稳定状态),应用的响应时间:P99等于三百毫秒。
性能提升 :
面试加分回答模板
面试官 :"你是如何进行 JVM 调优的?"
标准回答 :
"JVM 调优我一般按照以下步骤:
1. 了解业务场景 :
Web应用:关注响应时间,选择 G1 GC
批处理:关注吞吐量,选择 GC
实时系统:关注延迟,选择 ZGC
2. 设置基础参数 :
堆内存,-Xms与-Xmx需设置为相同之值,一般而言,此值处于物理内存的70%至80%区间 。
栈大小: - (Web应用)
元空间: -XX:=256m -XX:=512m
3. 选择 GC 策略 :
堆内存 < 6GB: GC
把堆内存设置在6到64GB的范围这儿,采用G1 GC这种方式,并且有设定 -XX:=200 这个操作 。
堆内存 > 64GB:ZGC(JDK 15+)
4. 开启 GC 日志和监控 :
生产环境必开: -Xlog:gc*:file=gc.log
OOM 自动 Dump: -XX:+
5. 压测验证 :
用 压测,观察 GC 频率和停顿时间
用 分析 GC 日志
根据结果调整参数
实际事例 :往昔我碰到过一个应用Full GC频繁出现的状况 ,借助剖析GC日志察觉老年代始终处于满的状态 ,最终运用MAT进行分析得知是静态缓存致使的内存泄漏 。修复完毕后 ,协同调整G1参数 ,Full GC全然消失 ,P99延迟由2秒降至200ms 。
快速参考手册常用参数速查表
| 参数 | 作用 | 推荐值 | | ---
|-Xms|那被称作初始堆内存的,它跟 –Xmx是保持一致的,|,|-Xmx|此为最大堆内存,其大小是物理内存乖以百分之七十五,|;|-Xss|这个线程栈大小呢,它设定为二百五十六k,|;|-Xmn|新生代大小这一项,它是不进行设置的,而是让垃圾回收机制自行去处理,| ;|-XX:|元空间初始大小被规定为二百五十六m,| ;|-XX:|元空间最大大小则设定为五百一十二m,| ;|-XX:+ |对于使用G1垃圾回收器这种举措codejock xtreme toolkit,它是被推荐采用的形式,| ;|-XX:|最大垃圾回收停顿时间被设定为二百,| ;|-XX:+| 。
| OOM 时 Dump | 必开 |
不同场景推荐配置
| 场景 | 堆内存 | GC | 目标 | | ---
有这样一些情况,开发环境的配置是512M,采用G1,具有快速启动特性,;Web应用方面,配置为4到8G,采用G1,有着低延迟特点,;微服务的配置是1到2G,采用G1,表现为均衡,;大数据批处理的配置是16到32G,采用特定方式,有着高吞吐特性,;实时系统的配置是32到64G,采用ZGC,拥有极低延迟特性,;容器环境的配置是容器的75%,采用G1,具备资源隔离特性。
总结
JVM 调优的本质 :
知悉业务,于不同场景运用不同策略,进行合理配置,涵盖堆内存、GC以及日志,实施监控分析,针对GC日志、Heap Dump展开,持续推进优化,基于压测、调整以及验证来达成 。
记住这些黄金法则 :
最后一句话 :
调优三步走:
1. 先看GC日志(发现问题)
2. 再调JVM参数(解决问题)
3. 最后压测验证(确认效果)
耐心观察,数据说话!
祝你的 JVM 跑得又快又稳!
如有侵权请联系删除!
Copyright © 2023 江苏优软数字科技有限公司 All Rights Reserved.正版sublime text、Codejock、IntelliJ IDEA、sketch、Mestrenova、DNAstar服务提供商
13262879759
微信二维码