解决Tomcat 服务不定时被linux OOM kill掉的问题

最近遇到一个很头疼的问题,发布到测试服务器的tomcat中跑的java应用,频繁无故停止,并且查询catalina.out日志中并没有tomcat停止的相应记录,后来在主机的/var/log/messages文件中发现了端倪,原来是被linux 的OOM kill掉了,下面是tomcat被kill掉的截图记录




看到记录后开始思考为什么tomcat应用的vm总内存可以达到7G之多,要知道我的服务器的总内存才8G,且其上还运行了其他的应用,首先想到的是发生了内存泄露,于是开始配置jvm参数,打开gc日志以及溢出记录,以下是我设置jvm启动参数(jdk8)

vim tomcat8/bin/catalina.sh 文件最上面添加以下


JAVA_OPTS='-Xms512m -Xmx512m -XX:MetaspaceSize=128m -XX:MaxDirectMemorySize=40m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/wilson/dump -XX:+PrintGCDetails -Xloggc:/wilson/gc.log -XX:+PrintGCTimeStamps'


参数解释:

    -Xms512m  初始化jvm堆内存大小

    -XmX512m  jvm堆内存最大值

    -XX:MetaspaceSize=128m  初始化元空间内存大小(此处由于我使用的是jdk1.8,官方改用元空间替换原来的持久代,默认对于64位的server vm该值的初始值为21m,在jvm启动时,一旦元空间的值达到21m,便会触发Full GC 去卸载没有用的类,然后该值的大小会重置,新值的大小将取决与 GC 后释放了多少元空间,若释放的空间不足,会充值并提升该值的大小,若释放的空间过多,则降低该值的大小,所以如果该值的初始化值过小,会导致在jvm启动时频繁的触发Full GC去调整,即会导致启动时间增加)

    -XX:MaxMetaspaceSize  最大元空间大小,默认没有上线,取决于主机的内存

    -XX:MaxDirectMemorySize=40m  最大nio堆外内存大小(注意该参数只是限制nio堆外内存,堆外内存占用还有其他的部分)

    -XX:+HeapDumpOnOutOfMemoryError 开启堆内存溢出生成dump文件

    -XX:HeapDumpPath=/wilson/dump  生成dump文件位置

    -XX:+PrintGCDetails  开启生成gc详细日志

    -Xloggc:/wilson/gc.log  gc文件日志

    -XX:+PrintGCTimeStamps  设置开启gc时间格式

参数配置完毕重启tomcat,观察gc情况以及是否发生内存泄露

启动完毕后,查询tomcat进程的pid :

netstat -apn | grep <你的tomcat端口>

再命令行输入: jmap -heap 可以查看jvm参数设置情况,以及简单的堆内存占用情况发现堆内存占用情况一直处于正常的水平中,通过gc.log文件看也是正常的,并且没有发生过内存泄露生成过dump文件,为此专门安装了可视化工具JProfiler

JProfiler安装链接:JProfiler安装并连接linux服务器

那么,问题来了,究竟是什么原因引起的tomcat内存占用将近7个g的呢?继续往下看

猜想可能是发生其他堆外内存泄露,导致tomcat占用内存飙升。分析堆外内存的话需要通过google-perftools分析了

google-perftools安装连接:google-perftools安装

安装完google-perftools之后,重启tomcat,持续观察其内存占用情况,未完待续......


    

    

你可能感兴趣的:(解决Tomcat 服务不定时被linux OOM kill掉的问题)