首先需要定位内存溢出的具体原因,这是解决问题的核心。查看Tomcat日志(通常位于/opt/apache-tomcat/logs/catalina.out或/var/log/tomcatX/catalina.out),搜索OutOfMemoryError关键字,常见的错误类型包括:
Java heap space:堆内存不足(最常见);PermGen space(Java 7及之前)/Metaspace(Java 8及以上):方法区/元空间溢出;unable to create new native thread:系统线程资源耗尽。jconsole、jvisualvm、jstat)实时监控内存使用情况,或通过jmap生成堆转储文件,用MAT(Memory Analyzer Tool)分析内存泄漏点。根据诊断结果调整Tomcat的JVM启动参数(修改bin/catalina.sh文件,在文件开头添加JAVA_OPTS配置):
-Xms)和最大堆大小(-Xmx),建议设置为物理内存的1/4至1/2(如-Xms1024m -Xmx2048m),避免设置过大导致系统内存不足;-XX:PermSize(初始永久代大小)和-XX:MaxPermSize(最大永久代大小),如-XX:PermSize=256m -XX:MaxPermSize=512m;-XX:MetaspaceSize(初始元空间大小)和-XX:MaxMetaspaceSize(最大元空间大小),如-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m;-XX:+UseG1GC启用G1回收器,适用于大内存应用),并调整相关参数(如-XX:MaxGCPauseMillis设置最大GC停顿时间)。内存溢出的根本原因往往是代码问题,需重点排查以下场景:
MAT分析堆转储文件,查找未释放的对象(如ThreadLocal未清理、静态集合持有对象引用、类加载器泄漏);new SimpleDateFormat()移到循环外复用);HikariCP、Apache DBCP),减少对象创建和销毁的开销。/etc/sysctl.conf文件,优化系统内存管理(如vm.max_map_count=262144增加内存映射区域数量,fs.file-max=65536增加文件描述符上限),然后执行sysctl -p使配置生效;conf/server.xml调整线程池大小(maxThreads参数,默认200,可根据CPU核心数调整,如maxThreads="500"),避免线程过多导致内存耗尽。top、htop命令监控Tomcat进程的内存使用情况(RES列表示实际内存占用),或通过jstat -gc <pid>查看GC情况(如Eden区、Old区的使用率);以上步骤覆盖了从诊断到解决的全流程,需根据实际场景组合使用。例如,若日志显示Java heap space,优先调整堆内存大小并优化代码;若显示Metaspace溢出,则增加元空间大小并清理无用类加载器。