温馨提示×

Ubuntu下Tomcat内存溢出怎么办

小樊
36
2025-11-23 09:33:56
栏目: 智能运维

Ubuntu下Tomcat内存溢出定位与处理

一、快速判断与定位

  • 查看异常类型与位置:在 $CATALINA_HOME/logs/catalina.out 中搜索关键字 OutOfMemoryError,常见类型包括:
    • Java heap space:堆内存不足,通常伴随大量对象创建或缓存失控。
    • PermGen space / Metaspace:类元数据区不足,常见于应用频繁热部署、加载大量第三方 JAR、JSP 预编译等场景(JDK 8+ 使用 Metaspace 替代 PermGen)。
    • 若日志出现大量线程堆栈或访问变慢,也可能与线程、连接或文件句柄等资源限制相关。以上判断路径与异常含义可参考常见 Tomcat OOM 案例与说明。

二、立即缓解 调整JVM内存参数

  • 编辑 $CATALINA_HOME/bin/catalina.sh,在合适位置(如注释行 “#JAVA_OPTS=…” 之后或 “cygwin=false” 之前)加入 JAVA_OPTS。示例(按机器内存与负载调整,以下为常见做法):
    • JDK 7 及更早(存在 PermGen):
      JAVA_OPTS="-server -Xms1024m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=512m"
      
    • JDK 8+(使用 Metaspace,不再设置 PermSize/MaxPermSize):
      JAVA_OPTS="-server -Xms1024m -Xmx1024m -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m"
      
    • 说明:
      • -Xms/-Xmx 建议设为相同值以减少 GC 波动;初始值可从 1–2GB 起步,视物理内存与容器数量调整。
      • 修改后重启 Tomcat 生效:$CATALINA_HOME/bin/shutdown.sh && $CATALINA_HOME/bin/startup.sh
    • 以上参数设置方法与常见 OOM 对应调整思路可参考多篇生产实践总结。

三、根因排查与优化

  • 堆内存问题(Java heap space)
    • 抓取堆转储:在 catalina.shJAVA_OPTS 中临时加入
      -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/tomcat/heapdumps
      
      发生 OOM 时自动生成 .hprof 文件,使用 Eclipse MAT 等工具分析“支配树/GC Roots”,定位占用最多的对象与引用链。
    • 结合代码审查缓存、会话、批量处理、文件/图片等大对象生命周期;必要时引入对象池或流式处理,避免一次性加载过多数据。
  • 元空间问题(PermGen/Metaspace)
    • 减少应用与类加载器泄漏:避免频繁热部署、清理 WEB-INF/lib 中重复或过大的 JAR、控制框架版本与插件数量。
    • 若使用 JDK 8+,优先通过 -XX:MaxMetaspaceSize 设置上限,观察是否仍持续增长。
  • 资源与系统层面
    • 检查 ulimit -a(如 open filesmax user processes),必要时提升限制;使用 lsof -n | awk '{print $2}' | sort | uniq -c | sort -nr | head 排查进程打开文件数是否异常。
    • catalina.out 过大导致写入缓慢或占用过高,配置 Cronolog 按时间滚动切割日志,降低单文件与内存压力。

四、实用参数模板与建议

  • 通用起步模板(JDK 8+,可按需微调):
    JAVA_OPTS="\
      -server \
      -Xms2048m -Xmx2048m \
      -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m \
      -Xss256k \
      -XX:+UseG1GC \
      -XX:MaxGCPauseMillis=200 \
      -XX:+HeapDumpOnOutOfMemoryError \
      -XX:HeapDumpPath=/opt/tomcat/heapdumps \
      -Djava.awt.headless=true"
    
    • 建议将 -Xms-Xmx 设为相同;使用 G1 GC 适配大堆与停顿目标;开启 HeapDumpOnOutOfMemoryError 便于事后分析。
    • 若运行在容器/虚拟化环境,确保给 JVM 分配的内存不超过宿主机可用内存,并预留给系统与其他进程。

0