首先需要确认内存溢出的具体类型(如堆内存、元空间、线程数等),以便针对性解决。常见方法包括:
/opt/tomcat/logs/catalina.out(或自定义日志路径)中的OutOfMemoryError信息,例如“java.lang.OutOfMemoryError: Java heap space”(堆内存溢出)、“java.lang.OutOfMemoryError: Metaspace”(元空间溢出)。jconsole、jvisualvm(JDK自带)或YourKit、JProfiler(第三方)监控Tomcat进程的内存使用情况,观察堆内存、元空间、线程数等指标的变化趋势。jmap生成堆转储文件(jmap -dump:live,format=b,file=heapdump.hprof <Tomcat_PID>),再用Eclipse MAT(Memory Analyzer Tool)分析对象占用情况,定位内存泄漏点(如大量未释放的对象、静态集合持有对象等)。根据诊断结果调整Tomcat的JVM启动参数(修改/opt/tomcat/bin/catalina.sh文件,添加或修改JAVA_OPTS或CATALINA_OPTS变量):
-Xms)和最大堆大小(-Xmx),建议两者保持一致以避免频繁扩容(如-Xms2048m -Xmx4096m,根据服务器内存调整,不超过物理内存的70%)。-XX:MetaspaceSize)和最大大小(-XX:MaxMetaspaceSize),避免元空间溢出(如-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m)。-XX:+UseG1GC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/opt/tomcat/logs/gc.log)。内存溢出的根本原因往往是代码中的内存泄漏或不合理的对象使用,需重点检查:
ThreadLocal(在finally块中调用remove()方法)、避免静态集合长期持有对象(如static Map)、正确关闭资源(如数据库连接、IO流,使用try-with-resources语句)。new String()、new ArrayList()),尽量重用对象(如使用对象池管理数据库连接)。优化Tomcat的连接器(Connector)配置,减少并发请求对内存的压力:
/opt/tomcat/conf/server.xml中的<Connector>标签,调整maxThreads(最大线程数,默认200,可根据服务器CPU核心数调整,如maxThreads="500")、acceptCount(等待队列长度,默认100,避免过长导致内存堆积)。connectionTimeout(连接超时时间,默认60000ms),避免长时间占用连接导致内存无法释放。确保操作系统配置不会成为瓶颈:
ulimit -n查看当前限制(默认1024),修改/etc/security/limits.conf(添加* soft nofile 65535、* hard nofile 65535)并重启服务器。/etc/sysctl.conf,优化内存管理(如vm.swappiness=10降低交换分区使用,vm.overcommit_memory=1允许内存超额分配),然后执行sysctl -p生效。建立长效监控机制,及时发现内存问题:
Prometheus+Grafana、Zabbix等工具实时监控Tomcat的内存使用率、GC频率、线程数等指标,设置警报阈值(如堆内存使用率超过80%时报警)。通过以上步骤,可以逐步定位并解决CentOS环境下Tomcat的内存溢出问题。需根据实际应用场景和服务器配置调整参数,避免盲目增大内存导致其他问题。