Ubuntu上Tomcat内存溢出的解决方法
首先需要确认内存溢出的具体类型(如堆内存溢出、永久代/元空间溢出等),通过Tomcat日志定位问题。日志文件通常位于/var/log/tomcatX/(X为实例编号)或/opt/tomcat/logs/目录下,使用以下命令过滤关键错误:
grep "OutOfMemoryError" /var/log/tomcatX/catalina.out # 查找内存溢出错误
grep "GC overhead limit exceeded" /var/log/tomcatX/catalina.out # 查找GC开销过大错误
根据日志中的OutOfMemoryError子类型(如Java heap space、PermGen space、Metaspace),针对性调整JVM参数。
若日志提示Java heap space(堆内存不足),需修改Tomcat启动脚本catalina.sh(位于TOMCAT_HOME/bin/),增加堆内存初始大小(-Xms)和最大大小(-Xmx)。例如:
# 在catalina.sh开头(cygwin=false前)添加以下参数
JAVA_OPTS="-server -Xms1024m -Xmx2048m"
-Xms1024m:设置堆初始大小为1GB;-Xmx2048m:设置堆最大大小为2GB(不超过服务器物理内存的70%,避免影响系统和其他进程)。PermGen space(永久代内存不足),需添加永久代大小参数:JAVA_OPTS="$JAVA_OPTS -XX:PermSize=256m -XX:MaxPermSize=512m"
JAVA_OPTS="$JAVA_OPTS -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m"
元空间使用本地内存,默认无上限,但建议设置合理范围以避免占用过多系统内存。若频繁出现Full GC或GC停顿时间长,可调整垃圾回收器参数。例如,使用CMS垃圾回收器(适用于Java 8及以下):
JAVA_OPTS="$JAVA_OPTS -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSCompactAtFullCollection"
-XX:+UseConcMarkSweepGC:启用CMS并发垃圾回收器;-XX:CMSInitiatingOccupancyFraction=70:当老年代占用70%时触发CMS回收;-XX:+UseCMSCompactAtFullCollection:Full GC后压缩老年代,减少碎片。修改参数后,重启Tomcat使配置生效:
sudo systemctl restart tomcat # Ubuntu系统使用systemctl管理Tomcat服务
使用以下工具监控内存使用情况:
-gcutil显示各内存池使用率):jstat -gcutil <Tomcat_PID> 1000 5 # 每1秒采样一次,共5次
catalina.out中的GC记录),生成可视化报告。jmap生成):jmap -dump:format=b,file=heap_dump.hprof <Tomcat_PID> # 生成堆转储文件