首先需要定位内存溢出的具体类型(如堆内存不足、元空间溢出、线程耗尽等),这是解决问题的关键。
/var/log/tomcat/catalina.out或localhost.log,搜索OutOfMemoryError关键字,常见错误包括:
java.lang.OutOfMemoryError: Java heap space(堆内存不足);java.lang.OutOfMemoryError: Metaspace(元空间溢出,Java 8+);java.lang.OutOfMemoryError: unable to create new native thread(线程资源耗尽)。top -p $(pgrep -f tomcat)查看Tomcat进程的内存、CPU占用;用ps -eLf | grep tomcat | wc -l统计线程数,判断是否因线程过多导致崩溃。内存溢出的核心原因是JVM内存分配不足,需根据服务器配置和应用需求调整参数(修改bin/setenv.sh,若不存在则创建):
-Xms)和最大堆(-Xmx)为相同值(避免动态调整开销),建议不超过系统物理内存的70%。例如:export JAVA_OPTS="-Xms1024m -Xmx2048m -XX:MaxMetaspaceSize=512m"
(-Xms1024m:初始堆1GB;-Xmx2048m:最大堆2GB;-XX:MaxMetaspaceSize=512m:元空间最大512MB,适用于Java 8+)。export JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -Xloggc:$CATALINA_BASE/logs/gc.log"
通过jstat -gcutil $(pgrep -f tomcat) 1000实时查看GC情况(FGC列高表示频繁Full GC,需调整堆大小或GC策略)。若调整内存后仍频繁溢出,需排查应用代码或第三方库的内存泄漏问题:
jmap命令生成堆快照(需替换为Tomcat进程ID):jmap -dump:format=b,file=/tmp/heap.hprof $(pgrep -f tomcat)
Eclipse MAT(Memory Analyzer Tool)打开heap.hprof,查找占用内存最多的对象(如静态集合、未关闭的数据库连接),定位泄漏源。static Map未清理);try-with-resources或finally块关闭);conf/server.xml中的Connector配置,避免线程池耗尽(根据服务器CPU核心数调整,推荐maxThreads = 核心数 * 200):<Connector port="8080" protocol="HTTP/1.1"
maxThreads="200"
minSpareThreads="20"
acceptCount="100" />
maximumSize(如maximumSize=1000),避免缓存无限增长。examples、docs等应用,减少内存占用。Too many open files错误,需增加系统限制(修改/etc/security/limits.conf):tomcat soft nofile 65535
tomcat hard nofile 65535
(tomcat为运行Tomcat的用户,nofile为文件描述符最大数量)。Manager App(/manager/html)监控应用状态,配置日志轮转(logrotate)避免日志占满磁盘。