如何限制Tomcat内存分配,确保不超出设定阈值?
Tomcat内存超限排查与解决方法
先确认setenv.sh配置是否真的生效
- 首先检查文件位置:setenv.sh必须放在Tomcat的
bin目录下,Linux/Unix系统还要给执行权限:chmod +x setenv.sh,不然启动脚本读不了它 - 正确的内存配置示例(别漏了元空间和直接内存):
export CATALINA_OPTS="-Xms512m -Xmx1024m -XX:MaxMetaspaceSize=256m -XX:MaxDirectMemorySize=256m" - 验证配置:Tomcat启动后,用
jps -v找到对应的进程,看输出里有没有你设置的这些参数。如果没有,要么是setenv.sh没被加载(比如自定义了启动脚本跳过了它),要么是配置写错了(比如拼写错误,比如把Xmx写成其他错误格式)
内存超限的常见坑
- 漏了元空间限制:JDK8+用元空间存类信息,默认无上限,会一直占用系统内存,必须显式设置
-XX:MaxMetaspaceSize - 直接内存没限制:NIO、数据库驱动这类组件会使用直接内存,这部分不算堆内存,默认和
-Xmx大小一致,要是程序大量用直接内存,总内存肯定超,得加-XX:MaxDirectMemorySize限制 - 线程栈内存忽略:每个线程默认栈内存1M(
-Xss1m),要是系统有几百个线程,这部分加起来就是几百M,不在堆统计范围内。线程多的话可以调小-Xss,比如-Xss512k - 代码/依赖内存泄漏:比如静态集合一直持有对象、数据库连接未关闭、流未释放,堆内存会持续增长,GC也无法清理,时间久了不仅堆内存接近上限,进程总内存也会飙升
完整的内存控制配置
给个能覆盖大部分场景的setenv.sh示例,根据你的实际需求调整数值:
#!/bin/bash # 堆内存:初始值512M,上限1G export CATALINA_OPTS="-Xms512m -Xmx1024m" # 元空间上限256M export CATALINA_OPTS="$CATALINA_OPTS -XX:MaxMetaspaceSize=256m" # 直接内存上限256M export CATALINA_OPTS="$CATALINA_OPTS -XX:MaxDirectMemorySize=256m" # 线程栈大小调为512K(根据线程数量调整) export CATALINA_OPTS="$CATALINA_OPTS -Xss512k" # 可选:加GC日志方便排查内存问题 export CATALINA_OPTS="$CATALINA_OPTS -Xloggc:/opt/tomcat/logs/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps"
验证内存是否合规
- 用
jstat -gc <Tomcat进程PID>查看堆和元空间的使用量,确认没超设定值 - 用
top查看进程的RES列(常驻内存),总内存应该接近「堆上限+元空间上限+直接内存上限+线程数×Xss」,误差在几十M以内是正常的(JVM本身还有一些基础开销) - 要是还是超,就抓堆快照分析:
jmap -dump:format=b,file=heap.hprof <PID>,用MAT工具打开找内存泄漏点
内容的提问来源于stack exchange,提问作者Manas D
相关产品推荐
相关产品推荐

