温馨提示×

Ubuntu上如何解决Tomcat内存溢出

小樊
40
2025-11-29 08:10:48
栏目: 智能运维

Ubuntu上解决Tomcat内存溢出的实用步骤

一、快速定位问题类型

  • 查看 $CATALINA_HOME/logs/catalina.outcatalina.[日期].log,根据异常关键字判断类型:
    • Java heap space:堆内存不足,常见于大数据量、缓存或内存泄漏。
    • PermGen space(JDK 7 及更早):永久代空间不足,常见于热部署、加载大量类/JAR。
    • Metaspace(JDK 8+):元空间不足,类元数据过多或动态生成类导致。
    • 也可能是系统层面限制(如 ulimit -a 打开文件数、虚拟内存等)引发间接异常。以上判断与处理思路可参考典型报错与排查经验。

二、调整JVM内存参数

  • 推荐在 $CATALINA_HOME/bin/setenv.sh 中设置(没有则创建),避免直接改动 catalina.sh 的通用环境段;使用 JAVA_OPTSCATALINA_OPTS 均可,二者区别是后者仅用于Tomcat启动脚本自身。
  • 按JDK版本选择参数:
    • JDK 8 及更早(含 PermGen)
      • 示例:JAVA_OPTS=“-Xms1024m -Xmx2048m -XX:PermSize=256m -XX:MaxPermSize=512m”
      • 含义:-Xms/-Xmx 为堆初始/最大;-XX:PermSize/-XX:MaxPermSize 为永久代初始/最大。
    • JDK 8+(使用 Metaspace)
      • 示例:JAVA_OPTS=“-Xms1024m -Xmx2048m -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m”
      • 含义:用 Metaspace 替代 PermGen;如无显式泄漏,可仅设置上限,初始值可较小。
  • 一般建议 -Xms 与 -Xmx 设为相同,减少堆扩容带来的抖动;同时结合物理内存与容器/系统限制合理取值。

三、启用GC日志与内存分析

  • setenv.sh 追加GC日志参数,便于定位是频繁 Full GC 还是内存泄漏:
    • JDK 8 示例:
      • JAVA_OPTS=“$JAVA_OPTS -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -Xloggc:$CATALINA_BASE/logs/gc.log”
    • JDK 9+ 建议使用统一日志(示例):
      • JAVA_OPTS=“$JAVA_OPTS -Xlog:gc*,gc+heap=debug:file=$CATALINA_BASE/logs/gc.log:time”
  • 使用工具(如 GCEasy)分析 GC 日志,关注 Full GC 次数/耗时、晋升失败、元空间/堆使用曲线,从而决定是继续加内存还是优化应用。

四、应用与系统层面的优化

  • 应用侧排查与优化(治本):
    • 杜绝资源泄漏:确保 Connection/Stream/Reader 等在 try-with-resources/finally 中关闭。
    • 控制缓存规模:为 Ehcache/Guava Cache 设置 maximumSize 与过期策略。
    • 大数据分批处理:避免一次性将大文件/大表全量加载到内存。
    • 减少热部署频率与重复加载类,避免类加载器泄漏。
  • 系统侧检查与优化:
    • 检查 ulimit -a(如 open filesvirtual memory 等),必要时在 /etc/security/limits.conf 或 systemd 服务单元中提升限制。
    • catalina.out 过大影响I/O与内存占用,使用 Cronolog 按时间滚动切割日志。

五、重启验证与参数建议

  • 重启并验证:
    • 重启方式:systemd 执行 sudo systemctl restart tomcat;或直接执行 $CATALINA_HOME/bin/startup.sh
    • 验证参数:执行 ps -ef | grep java 查看是否包含你设置的 -Xms/-Xmx/-XX:MetaspaceSize 等值;查看 catalina.out 启动日志确认无 OOM;观察 gc.log 是否恢复正常。
  • 参数起步建议(按机器内存与负载调整):
    • 4GB 内存机器:JDK 8 示例 -Xms1024m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=512m;JDK 8+ 示例 -Xms1024m -Xmx1024m -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m
    • 8GB 内存机器:JDK 8+ 示例 -Xms2048m -Xmx2048m -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m
    • 生产环境优先保证 -Xms=-Xmx、为系统与其他服务预留充足内存,再结合 GC 日志逐步微调。

0