1. 环境与背景
Tomcat 8.5.85
JAVA 1.8.0_91
背景:Tomcat的jvm内存溢出
2. 原始配置
ps -ef | grep java 查看进程id
jinfo -flags id号 查看参数
shell
# 原始JVM参数
# 堆内存相关
-XX:InitialHeapSize=257535932 # ≈ 246MB
-XX:MaxHeapSize=4026531842 # ≈ 3.75GB
-XX:NewSize=84410368 # ≈ 80.5MB
-XX:MaxNewSize=13421701568 # ≈ 12.5GB
-XX:OldSize=169345024 # ≈ 161.5MB
# 元空间相关(无显式配置,使用JVM默认值)
# -XX:MetaspaceSize=21807104 # 默认≈21MB
# -XX:MaxMetaspaceSize=-1 # 默认无上限
# 垃圾收集器
-XX:+UseParallelGC # 默认并行收集器(吞吐量优先)
# 其他默认参数
-XX:SurvivorRatio=8 # Eden:S0:S1=8:1:1(默认值)
存在的问题
shell
堆内存初始值(246MB)与最大值(3.75GB)差值过大,启动后频繁扩容引发 GC 停顿;
新生代最大值(12.5GB)远超堆内存上限(3.75GB),配置逻辑异常;
元空间无显式配置,类加载过多时易触发元空间 OOM;
默认 ParallelGC 收集器停顿时间长,不适合 Web 应用低延迟需求。
3. 优化
tomcat的bin目录下面新建 setenv.sh文件
适配16GB物理内存服务器,超过16G的需要更改参数!!!
shell
#!/bin/bash
export JAVA_OPTS="${JAVA_OPTS} -Xms6g -Xmx6g -XX:NewSize=2g -XX:MaxNewSize=2g -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=1024m -XX:SurvivorRatio=8 -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/app/tomcat/tomcat-8080/logs/heapdump.hprof -Djava.awt.headless=true -Dorg.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER=true"
chmod +x setenv.sh 加上权限
./shutdown.sh && ./startup.sh 重启Tomcat
| 参数 | 优化后值 | 对比原始配置的调整 | 核心作用 |
|---|---|---|---|
-Xms6g -Xmx6g |
6GB | 替代 246MB/3.75GB | 固定堆内存大小,消除扩容 / 缩容引发的 GC 停顿 |
-XX:NewSize=2g -XX:MaxNewSize=2g |
2GB | 替代 80.5MB/12.5GB | 固定新生代大小(堆内存 1/3),Minor GC 频率更稳定 |
-XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=1024m |
512MB/1GB | 替代默认 21MB / 无上限 | 预留充足元空间,避免类加载过多导致的 OOM |
-XX:+UseG1GC |
G1 收集器 | 替代 ParallelGC | 低延迟优先,Full GC 停顿时间控制在 100ms 内 |
-XX:G1HeapRegionSize=16m |
16MB | 新增配置 | 适配 6GB 堆内存,提升 G1 垃圾收集效 |
重启后若Tomcat状态异常则使用tail -100 /app/tomcat/tomcat-8080/logs/catalina.out查看报错