从日志入手定位内存瓶颈,再按“先止损、再定位、后优化”的顺序调整 Tomcat 内存与配置,能显著降低 OOM 与 Full GC 风险。
一、从日志快速定位内存问题
-
识别 OOM 类型
在 catalina.out 或应用日志中查找关键词:
- java.lang.OutOfMemoryError: Java heap space → 堆内存不足,需调整堆大小或修复对象膨胀/泄漏。
- java.lang.OutOfMemoryError: Metaspace → 类元数据过多,需调整 MaxMetaspaceSize 或清理无用类加载。
- java.lang.OutOfMemoryError: unable to create new native thread → 线程/系统资源不足,需降低并发或放宽系统限制。
- 伴随大量 GC 日志且回收效果差,常见于对象生命周期过长或泄漏。
以上错误类型与处理方向可结合日志与后续工具验证。
-
打开并保留 GC 日志
在 catalina.sh/catalina.bat 的 JAVA_OPTS/CATALINA_OPTS 中加入(示例为 JDK 8+):
- -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/opt/tomcat/logs/gc.log
通过 GC 日志观察:
- 是否频繁 Young/Full GC、回收前后占用变化、停顿时间是否过长(如单次超过 3–5 秒 需重点优化)。
- 是否出现 Allocation Failure 或 Metadata GC Threshold 等提示,从而决定堆/元空间与 GC 策略调整方向。
-
触发并分析堆转储
在发现持续 Full GC 或 OOM 前,主动触发一次堆快照:
- 使用 jmap -dump:format=b,file=heap.hprof 获取 Heap Dump;
- 用 MAT(Memory Analyzer Tool)/VisualVM 分析占用最高的对象与 GC Roots 引用链,定位泄漏点或大对象来源。
二、止损与快速修复
三、基于日志的定向优化
-
堆与 GC 策略
- 目标是减少 Full GC 次数与停顿:
- 大堆、对象生命周期差异大时优先 G1GC:-XX:+UseG1GC;
- 吞吐优先可考虑 ParallelGC:-XX:+UseParallelGC;
- 结合 GC 日志验证回收效率与停顿时间,再微调各区大小与回收阈值。
-
连接器与线程模型
- 使用 NIO/NIO2 或启用 HTTP/2 提升并发与资源利用;
- 通过共享 统一管理线程池,按 CPU/IO 能力设置 maxThreads、minSpareThreads、acceptCount,避免线程风暴。
-
非堆与本地内存
- 若日志提示 Metaspace 压力,先清理无用依赖/类加载器,再设置 -XX:MaxMetaspaceSize 上限;
- 减少大对象缓存、批处理批量大小,避免一次性加载过多数据到内存。
-
应用层治理
- 规范资源关闭(流、连接、会话/缓存),避免静态集合无限增长;
- 对大文件/批量任务采用流式处理与分页/分批策略。
四、落地配置与验证清单