温馨提示×

Tomcat日志中出现OOM怎么办

小樊
66
2025-08-02 06:37:30
栏目: 智能运维

当Tomcat日志中出现OOM(Out of Memory)错误时,通常表示Java虚拟机无法分配足够的内存资源,导致应用程序崩溃或性能下降。以下是一些解决和预防Tomcat OOM问题的步骤:

快速诊断步骤

  1. 检查日志文件
  • 查看 catalina.outlocalhost.log 文件,寻找 OutOfMemoryErrorStackOverflowError 或线程死锁信息。
  1. 监控资源使用
  • 实时查看内存和CPU使用情况:
top -p $(pgrep -f tomcat)
  • 检查线程数:
ps -eLf | grep tomcat | wc -l

常见原因及解决方案

1. 内存不足(OOM)

  • 现象java.lang.OutOfMemoryError: Java heap space
  • 解决方法
  • 调整JVM内存参数(在 setenv.sh 中设置):
export JAVA_OPTS="-Xms512m -Xmx1024m -XX:MaxMetaspaceSize=256m"
  • 建议:
  • XmsXmx 设为相同值避免动态调整开销。
  • 不超过系统物理内存的70%。

2. 线程池耗尽

  • 现象java.util.concurrent.TimeoutException 或请求卡死
  • 解决方法
  • 修改 conf/server.xml 的Connector配置:
<Connector
executor="tomcatThreadPool"
maxThreads="200" <!-- 默认200根据负载调整 -->
minSpareThreads="20"
acceptCount="100" <!-- 等待队列长度 -->
/>
  • 监控线程使用:
jstack $(pgrep -f tomcat) | grep "http-nio" | wc -l

3. 应用内存泄漏

  • 排查工具
  • 生成堆转储文件分析:
jmap -dump:format=b,file=/tmp/heap.hprof $(pgrep -f tomcat)
  • 使用 jvisualvmEclipse MAT 分析泄漏对象。
  • 常见泄漏源
  • 静态集合未清理、未关闭的数据库连接、第三方库Bug。

4. 文件描述符耗尽

  • 现象Too many open files
  • 解决方法
  • 检查限制:
ulimit -n
  • 修改系统限制(/etc/security/limits.conf):
tomcat soft nofile 65535
tomcat hard nofile 65535

5. 数据库连接池问题

  • 排查
  • 检查连接池配置(如 maxActive 是否过高)。
  • 监控数据库连接泄漏:
SHOW STATUS LIKE 'Threads_connected';

高级排查工具

  1. JVM监控
  • 使用 jstat 观察GC情况:
jstat -gcutil $(pgrep -f tomcat) 1000
  • 频繁Full GC(FGC列高)表明内存问题。
  1. 线程转储分析
  • 生成线程转储:
kill -3 $(pgrep -f tomcat) # 输出到catalina.out
  • 使用 fastthread.io 在线分析死锁。

预防措施

  1. 定期检查和优化应用代码
  • 确保没有内存泄漏,及时释放资源。
  1. 使用监控工具
  • 实时监控Tomcat和JVM的性能指标,及时发现并解决问题。

通过以上步骤,可以有效地诊断和解决Tomcat日志中的OOM问题,并采取措施预防未来的发生。

0