Debian Tomcat 日志出现内存溢出的处理步骤
一 快速定位 OOM 类型
- 查看 /var/log/tomcat/catalina.out* 或应用日志,确认异常类型:
- Java heap space:堆内存不足,常见于对象生命周期过长、缓存失控、一次性加载大数据等。
- PermGen space(Java 7 及更早):永久代不足,常见于热部署频繁、类加载器泄漏、第三方 JAR 过多。
- Metaspace(Java 8+):元空间不足,常见于类元数据持续增长、动态生成类过多。
- 伴随线程名如 http-nio-8080-exec-XX 的报错,多为请求处理线程触发 OOM。以上特征在 Tomcat 日志中都很典型。
二 应急缓解与配置路径
- 调整 JVM 内存参数(按 Java 版本区分):
- Java 7(Tomcat 7 常见):在 /etc/default/tomcat7 的 JAVA_OPTS 中设置
- 示例:JAVA_OPTS=“-Xms2g -Xmx2g -Xmn512m -XX:PermSize=256m -XX:MaxPermSize=512m”
- Java 8+(Tomcat 8/9/10):在 JAVA_OPTS 中设置
- 示例:JAVA_OPTS=“-Xms2g -Xmx2g -Xmn512m -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m”
- 建议将 -Xms 与 -Xmx 设为相同,减少 GC 震荡;可按应用负载与物理内存适度放大。修改后重启 Tomcat 生效。
- 若不是通过服务脚本启动,而是直接执行脚本,可在 bin/catalina.sh 中设置 JAVA_OPTS(放在 “cygwin=false” 之前)。
- 同步检查系统资源限制(如 ulimit -n 文件句柄),过低的句柄上限会导致各种异常,必要时调高并重启服务。
三 根因排查与修复
- 生成并分析堆转储(Heap Dump)
- 在 JAVA_OPTS 中临时加入:
- -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/log/tomcat/
- 用 JVisualVM、Eclipse MAT 打开 Dump,定位占用最高、引用链可疑的对象(如缓存 Map、静态集合、ThreadLocal、未关闭的流/会话/连接)。
- 代码与数据访问层面
- 修复资源泄漏:确保 Connection、Statement、ResultSet、InputStream/OutputStream、Session 等在使用后关闭;避免静态集合长期持有对象引用。
- 控制单次请求数据量:对查询做分页/游标、批量处理,避免一次性把十万级记录装入内存。
- 优化缓存策略:设置最大容量与过期策略(如 LRU),避免无限增长。
- 运行期观测
- 使用 JConsole/JVisualVM 观察堆、类、线程与 GC 行为;必要时开启 GC 日志 辅助判断回收效率与停顿特征。
四 常见场景与参数示例
- 场景 A:Java heap space
- 现象:日志出现 “Handler processing failed; nested exception is java.lang.OutOfMemoryError: Java heap space”。
- 处置:增大堆与年轻代,优化对象生命周期与大对象加载;必要时分析 Dump 找泄漏点。
- 示例(Java 8+):JAVA_OPTS=“-Xms4g -Xmx4g -Xmn1g -XX:+UseG1GC -XX:MaxMetaspaceSize=512m”
- 场景 B:PermGen space(Java 7)
- 现象:日志出现 “java.lang.OutOfMemoryError: PermGen space”,常见于热部署/类加载器泄漏。
- 处置:增大 PermSize/MaxPermSize,减少热部署频率,排查类加载器泄漏;升级到 Java 8+ 并使用 Metaspace 替代。
- 示例:JAVA_OPTS=“-Xms2g -Xmx2g -XX:PermSize=256m -XX:MaxPermSize=512m”
- 场景 C:Metaspace(Java 8+)
- 现象:日志出现 “java.lang.OutOfMemoryError: Metaspace”。
- 处置:设置 MaxMetaspaceSize,清理无用依赖与类加载器泄漏,控制动态类生成。
- 示例:JAVA_OPTS=“-Xms2g -Xmx2g -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m”
- 场景 D:文件句柄耗尽导致异常
- 现象:访问变慢/失败,系统检查到进程打开文件数远超 ulimit -n(如 1024)。
- 处置:调高 ulimit -n,检查连接泄漏与资源未关闭问题,再评估内存与并发配置。