在Tomcat conf/catalina.bat或catalina.sh中 的最上面增加参数
1. 初步调整参数(缓解问题)
set JAVA_OPTS=
-Xms6g -Xmx6g
-Xmn3g # 增大新生代,减少对象过早晋升到老年代
-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=1g
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:+ParallelRefProcEnabled # 加速引用处理
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=./heapdump.hprof
--JDK9使用参数
-Xlog:gc*,gc+heap=debug:file=./logs/gc.log:time,uptimemillis:filecount=10,filesize=10M
--JDK8及以下使用参数
-Xloggc:./logs/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=10M
--JDK9使用参数
set JAVA_OPTS= -Xms6g -Xmx6g -Xmn3g -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=1g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+ParallelRefProcEnabled -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./heapdump.hprof -Xlog:gc*,gc+heap=debug:file=./logs/gc.log:time,uptimemillis:filecount=10,filesize=10M
--JDK8及以下使用参数
set JAVA_OPTS= -Xms6g -Xmx6g -Xmn3g -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=1g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+ParallelRefProcEnabled -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./heapdump.hprof -Xloggc:./logs/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=10M
2. 堆外内存限制(若 Netty 使用 Direct Buffer)
-XX:MaxDirectMemorySize=2g # 限制堆外内存,默认与 -Xmx 相同
以下是每个参数的详细解释及其作用:
1. -Xms6g
和 -Xmx6g
含义:
-Xms6g
:设置 JVM 堆内存的初始大小为 6GB。-Xmx6g
:设置 JVM 堆内存的最大大小为 6GB。
作用:
将堆的初始值和最大值设为相同,避免堆动态扩展时的性能开销。
6GB 的堆大小适用于需要处理高并发或大数据的应用场景。
注意事项:
若堆内存不足(OOM 错误),需结合应用需求适当增大
-Xmx
,但需考虑物理内存限制。
2. -Xmn3g
含义:
设置 新生代(Young Generation)的大小为 3GB。
作用:
新生代是对象初次分配的区域,较大的新生代可减少对象过早晋升到老年代(Old Generation)的频率。
默认新生代与老年代比例为
1:2
(如-Xmn3g
时,老年代为6g - 3g = 3g
)。
调优场景:
适合短生命周期对象较多的应用(如 Web 请求的临时对象),减少 Full GC 频率。
3. -XX:MetaspaceSize=256m
和 -XX:MaxMetaspaceSize=1g
含义:
MetaspaceSize
:设置 元空间(Metaspace)的初始大小为 256MB。MaxMetaspaceSize
:设置 元空间的最大大小为 1GB。
作用:
元空间用于存储类的元数据(如类信息、方法字节码),取代 Java 8 之前的永久代(PermGen)。
设置初始大小避免频繁的元空间动态扩展;设置上限防止元空间无限膨胀(如类加载器泄漏)。
注意事项:
若应用频繁加载/卸载类(如动态代理),需适当增大
MaxMetaspaceSize
。
4. -XX:+UseG1GC
含义:
启用 G1(Garbage-First)垃圾回收器。
作用:
G1 是面向大堆(>4GB)的垃圾回收器,通过分代和分区(Region)策略,平衡吞吐量和低延迟。
特点:
并发标记:与用户线程并行执行部分 GC 操作。
可预测停顿:通过
MaxGCPauseMillis
控制目标停顿时间。混合回收:在回收新生代时,同时回收部分老年代。
5. -XX:MaxGCPauseMillis=200
含义:
设置 G1 垃圾回收器的 目标最大停顿时间为 200 毫秒。
作用:
G1 会尽量调整 GC 策略(如每次回收的 Region 数量)以满足该目标。
较小的值(如 50ms)会减少单次 GC 停顿时间,但可能增加 GC 频率。
注意事项:
这是一个“软目标”,JVM 会尽力达成,但不保证绝对不超过。
6. -XX:+ParallelRefProcEnabled
含义:
启用 并行处理引用对象(如软引用、弱引用、虚引用、Finalizer)。
作用:
加速引用对象的处理,减少 Full GC 的停顿时间。
默认情况下,引用处理是单线程的,可能成为 Full GC 的瓶颈。
7. -XX:+HeapDumpOnOutOfMemoryError
和 -XX:HeapDumpPath=./heapdump.hprof
含义:
HeapDumpOnOutOfMemoryError
:在发生 OOM 时自动生成堆转储(Heap Dump)。HeapDumpPath
:指定堆转储文件的保存路径(如./heapdump.hprof
)。
作用:
堆转储是内存快照,用于分析 OOM 时的内存占用情况(如内存泄漏)。
默认路径为当前工作目录,建议指定固定目录(如
./logs
)。
8. -Xlog:gc*,gc+heap=debug:file=./logs/gc.log:time,uptimemillis:filecount=10,filesize=10M
含义:
配置详细的 GC 日志输出。
参数分解:
gc*
:记录所有 GC 事件。gc+heap=debug
:启用堆内存变化的调试信息。file=./logs/gc.log
:日志文件路径。time,uptimemillis
:日志中显示时间戳和 JVM 启动后的毫秒数。filecount=10,filesize=10M
:保留最多 10 个日志文件,每个文件最大 10MB。
作用:
通过 GC 日志分析 GC 频率、停顿时间、内存回收效率。
示例日志片段:
复制
下载
[2023-10-01T12:34:56.789+0800][12345ms] GC(0) Pause Young (Normal) 2048M->512M(6144M) 50ms
9. -XX:MaxDirectMemorySize=2g
含义:
设置 JVM 堆外内存(Direct Memory)的最大大小为 2GB。
作用:
堆外内存由
ByteBuffer.allocateDirect()
或 Netty 的PooledByteBuf
分配,不经过 GC 管理。默认值为
-Xmx
(即与堆内存相同),显式设置可防止堆外内存泄漏导致系统崩溃。
注意事项:
Netty 等 NIO 框架大量使用堆外内存,需结合应用实际需求调整此值。
参数分类总结
类别 | 参数示例 | 核心作用 |
---|---|---|
堆内存 | -Xms6g -Xmx6g -Xmn3g |
控制堆大小及分代比例 |
元空间 | -XX:MetaspaceSize=256m |
管理类元数据内存 |
垃圾回收器 | -XX:+UseG1GC |
选择高效低延迟的 GC 算法 |
GC调优 | -XX:MaxGCPauseMillis=200 |
平衡吞吐量和停顿时间 |
诊断工具 | -XX:+HeapDumpOnOutOfMemoryError |
捕获 OOM 时的内存快照 |
日志与监控 | -Xlog:gc*... |
记录 GC 行为供后续分析 |
堆外内存 | -XX:MaxDirectMemorySize=2g |
防止堆外内存泄漏 |
最终建议
监控验证:
部署后使用
jstat
、jcmd
或 VisualVM 实时监控内存和 GC 行为。检查 GC 日志中 Full GC 的频率和耗时。
堆转储分析:
若再次发生 OOM,使用 MAT 分析
heapdump.hprof
,重点关注Retained Heap
最大的对象。
Netty 专项检查:
添加
-Dio.netty.leakDetection.level=PARANOID
参数,启用 Netty 内存泄漏检测。确保所有
ByteBuf
通过release()
释放。