首先需要通过日志或工具确认内存溢出的具体原因,常见错误包括:
catalina.out或应用日志),搜索OutOfMemoryError关键字;jconsole、jvisualvm或jmap工具监控内存使用情况;jmap -dump:format=b,file=heap.hprof <pid>),用MAT(Memory Analyzer Tool)分析内存泄漏点。修改Tomcat启动脚本catalina.sh(位于$CATALINA_HOME/bin/),添加或修改JAVA_OPTS参数,根据溢出类型调整:
增加堆内存大小,设置初始堆(-Xms)和最大堆(-Xmx)为相同值(避免频繁扩容),建议设置为物理内存的1/4~1/2(不超过系统可用内存)。
JAVA_OPTS="-server -Xms2048m -Xmx4096m -XX:+UseG1GC"
-server:启用服务器模式(提升性能);-Xms2048m:初始堆大小2GB;-Xmx4096m:最大堆大小4GB;-XX:+UseG1GC:使用G1垃圾回收器(适合大内存应用,减少Full GC停顿)。-XX:PermSize、-XX:MaxPermSize);-XX:MetaspaceSize、-XX:MaxMetaspaceSize),并设置系统属性-XX:+UseCompressedClassPointers(压缩类指针,节省空间)。# Java 8前
JAVA_OPTS="-server -Xms1024m -Xmx2048m -XX:PermSize=256m -XX:MaxPermSize=512m"
# Java 8+
JAVA_OPTS="-server -Xms1024m -Xmx2048m -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m -XX:+UseCompressedClassPointers"
注意:元空间默认无大小限制,但需避免设置过大(防止占用过多系统内存)。
调整系统线程限制(ulimit)和Tomcat线程池大小:
ulimit -u(默认通常为1024);ulimit -u 4096;/etc/security/limits.conf,添加tomcat_user hard nproc 8192(tomcat_user为运行Tomcat的用户);server.xml中<Connector>标签):<Connector port="8080" protocol="HTTP/1.1"
maxThreads="500"
minSpareThreads="50"
acceptCount="200" />
new Thread()无限制创建)。内存溢出的根本原因往往是代码问题,需针对性优化:
new String()、new ArrayList());InputStream、Connection、Session等资源在使用后调用close()方法(用try-with-resources语法);finally块中调用threadLocal.remove(),避免线程复用时内存泄漏。选择合适的垃圾回收器并优化其参数,提升内存回收效率:
-XX:+UseConcMarkSweepGC),减少Full GC停顿;-XX:+UseG1GC),适合大内存应用,自动调整堆分区;-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/path/to/gc.log,分析GC频率和耗时,调整堆大小或回收器参数。top、htop、free -m等命令监控CPU、内存、磁盘使用情况,及时发现瓶颈。-Xmx,观察内存使用趋势)。通过以上步骤,可有效解决Linux环境下Tomcat的内存溢出问题。需根据具体错误类型和系统环境灵活调整,优先通过代码优化减少内存消耗,再调整JVM参数和系统配置。