首页主机资讯如何解决Ubuntu Tomcat内存溢出问题

如何解决Ubuntu Tomcat内存溢出问题

时间2026-01-20 17:48:03发布访客分类主机资讯浏览1291
导读:Ubuntu 上 Tomcat 内存溢出的定位与解决 一、先快速定位 OOM 类型与触发点 查看 $CATALINA_HOME/logs/catalina.out 与 localhost.log*,根据异常关键字判断类型: Java h...

Ubuntu 上 Tomcat 内存溢出的定位与解决

一、先快速定位 OOM 类型与触发点

  • 查看 $CATALINA_HOME/logs/catalina.outlocalhost.log*,根据异常关键字判断类型:
    • Java heap space:堆内存不足,常见于大数据量、缓存或大对象。
    • PermGen space(JDK 7 及更早):永久代/元空间不足,常见于热部署、加载大量类/JAR。
    • Metaspace(JDK 8+):元空间不足,类加载过多或类加载器泄漏。
    • unable to create new native thread:线程数触顶,常与连接数、线程栈设置相关。
  • 用系统命令确认进程与资源:
    • 查进程:ps -ef | grep java
    • 看内存概要:jmap -heap
    • 看 GC 与内存代:jstat -gcutil 1000 30
    • 看线程与 CPU 占用:top -H -p ;定位占用最高线程后用 printf “%x\n” 转 16 进制,再用 jstack | grep -A 30 查栈。

二、针对性解决步骤

  • 堆内存不足(Java heap space)
    • 适度提升堆上限,建议 -Xms 与 -Xmx 设为相同,避免运行期扩缩带来的抖动;结合物理内存与容器/系统占用,一般不超过可用内存的 70%–80%
    • 示例(放到 catalina.sh 的合适位置):JAVA_OPTS=“$JAVA_OPTS -Xms2g -Xmx2g”
  • 永久代/元空间不足(PermGen/Metaspace)
    • JDK 7 及更早:增加 -XX:PermSize=… -XX:MaxPermSize=…
    • JDK 8+:使用 -XX:MetaspaceSize=… -XX:MaxMetaspaceSize=…(不设上限有风险,建议显式上限)。
    • 减少重复加载:将通用 JAR 放到 $CATALINA_HOME/shared/lib(或对应版本的解压目录结构),降低 Perm/Metaspace 压力。
  • 线程耗尽(unable to create new native thread)
    • 降低单线程栈:-Xss256k(默认通常较大,适当减小可创建更多线程,但过小会栈溢出)。
    • 合理控制并发:在 conf/server.xml 中调优 maxThreads(并发处理线程数)、acceptCount(排队队列长度)、connectionTimeout(超时)等参数,避免无界排队与线程风暴。

三、在 Ubuntu 正确设置 JVM 参数

  • 编辑 $CATALINA_HOME/bin/catalina.sh,在 “OS specific support …” 段之前添加(或追加到已有的 JAVA_OPTS),位置很关键,避免被后续脚本覆盖:
    • 示例(JDK 8+,含元空间与栈):
      JAVA_OPTS="$JAVA_OPTS \
        -server \
        -Xms2g -Xmx2g \
        -Xss256k \
        -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m \
        -Djava.awt.headless=true"
      
    • 如为 JDK 7:将 -XX:MetaspaceSize/MaxMetaspaceSize 替换为 -XX:PermSize=… -XX:MaxPermSize=…
  • 作为服务运行时(如通过 systemd 管理的 tomcat 服务),需把上述参数写入服务的 Environment=JAVA_OPTS=… 配置中,或在 /usr/share/tomcat9/bin/setenv.sh(若不存在可创建)中导出,确保服务启动脚本能读取到。
  • 重启并验证:sudo systemctl restart tomcat9,再用 jmap -heap jstat -gcutil 确认参数生效与 GC 状况。

四、应用侧优化与常见陷阱

  • 排查内存泄漏与对象膨胀:结合 jmap/jstackVisualVM/JConsole 做堆转储与热点分析,清理静态集合、缓存滥用、未关闭资源(如 InputStream/Connection)、大对象生命周期过长等问题。
  • 控制类加载与热部署频率:避免频繁 redeploy 导致 PermGen/Metaspace 持续增长;共享 JAR、减少 Web 应用私有副本。
  • 连接与线程治理:合理设置 maxThreads/acceptCount,并配合 Nginx/HAProxy 做连接限流与超时,防止雪崩与线程耗尽。

五、常用参数与监控命令速查

  • 常用 JVM 参数
    • 堆与栈:-Xms/-Xmx(建议等值)、-Xss(线程栈,如 256k
    • 元空间(JDK 8+):-XX:MetaspaceSize=… -XX:MaxMetaspaceSize=…
    • 永久代(JDK 7-):-XX:PermSize=… -XX:MaxPermSize=…
    • 模式与特性:-server-Djava.awt.headless=true
  • 常用监控命令
    • 进程:ps -ef | grep java
    • 堆与 GC:jmap -heap jstat -gcutil 1000 30
    • 线程与栈:top -H -p printf “%x\n” jstack | grep -A 30

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: 如何解决Ubuntu Tomcat内存溢出问题
本文地址: https://pptw.com/jishu/787458.html
Ubuntu Tomcat版本如何选择与升级 Ubuntu Tomcat日志如何查看与分析

游客 回复需填写必要信息