Linux环境下Tomcat内存溢出的解决方法
解决内存溢出的第一步是明确溢出根源,通过Tomcat日志(catalina.out或应用日志)查找OutOfMemoryError的具体信息,常见类型包括:
java.lang.OutOfMemoryError: Java heap space(堆内存不足)java.lang.OutOfMemoryError: PermGen space(永久代/元空间不足,Java 8前为PermGen,Java 8及以上为Metaspace)java.lang.OutOfMemoryError: unable to create new native thread(系统线程资源耗尽)catalina.sh(Tomcat bin目录下)通过设置JAVA_OPTS调整JVM内存大小,关键参数说明:
-Xms:初始堆内存(如-Xms512m,建议与-Xmx一致,避免频繁扩容)-Xmx:最大堆内存(如-Xmx2048m,不超过物理内存的80%)-XX:PermSize/-XX:MaxPermSize:永久代初始/最大大小(Java 7及之前,如-XX:PermSize=128m -XX:MaxPermSize=256m)-XX:MetaspaceSize/-XX:MaxMetaspaceSize:元空间初始/最大大小(Java 8及以上,如-XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m)示例配置(Java 8及以上,适配大多数场景):
export JAVA_OPTS="-server -Xms1024m -Xmx2048m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+UseG1GC"
说明:-server启用服务器模式(提升性能),-XX:+UseG1GC使用G1垃圾收集器(适合大内存场景)。
内存泄漏是导致溢出的常见隐性原因,需通过代码审查或内存分析工具(如VisualVM、MAT、jmap)定位泄漏点,常见场景及修复方法:
finally块中调用threadLocal.remove(),避免线程复用时对象无法回收。static Map)长期存储对象,使用后及时清空(如map.clear())。LIMIT 1000),避免将10万+条数据加载到内存。List、Map等集合对象使用完毕后,置为null,帮助GC回收。若错误为unable to create new native thread,需调整Linux系统的线程数限制:
ulimit -u
ulimit -u 65535
/etc/security/limits.conf):* soft nproc 65535
* hard nproc 65535
说明:nproc表示用户可创建的最大线程数,根据服务器配置调整(如4核8G内存可设为65535)。
对于无法快速定位的溢出问题,定期重启Tomcat可释放累积的内存。建议通过crontab设置定时任务(如每天凌晨3点重启):
0 3 * * * /usr/local/tomcat/bin/shutdown.sh && /usr/local/tomcat/bin/startup.sh
注意:此方案仅为临时缓解,需结合上述方法彻底解决问题。
优化后需持续监控Tomcat内存使用情况,验证配置有效性:
jvisualvm(JDK自带)或jconsole实时查看堆内存、线程数等指标。jstat -gcutil <pid>查看GC情况(如O表示老年代使用率,超过80%需警惕)。OutOfMemoryError抛出。通过以上步骤,可系统性解决Linux环境下Tomcat的内存溢出问题。需根据实际场景(如应用类型、数据量)调整参数,优先修复代码泄漏,再优化JVM配置。