总结:记一次内存溢出导致的tomcat频繁挂掉问题

一、问题背景

今天中午开始,几台线上服务器差不多在同个时间段相继挂掉,于是急忙排查故障原因。

二、原因分析

首先使用visualVM看资源使用情况,发现线程有2万多,甚至有的实例超过3万,于是通过jstack命令查看线程堆栈信息,看哪里代码生成太多的线程。

失望的是,只看到线程池名称,但是看不到具体是哪个代码类引起的问题。

于是另一种方式,换个角度,能否看到哪些对象占用空间大。使用jmap -dump命令,结果,生成的内存dump文件有20G,根本无法分析。

后来,同事提醒调小JVM最大使用内存(从30G调整到15G),观察了一段时间没有再出现问题(以为问题解决了,但是线程无限增大,理论上还是会内存溢出,后来发现确实不是这块的问题)。

第二天,又想了下这块原因,我们系统的线程池是公用的,理论上从代码层面产生的线程最多100个,不会更多,为什么会有超过3万?沿着这个思路想到,是否有人没有使用系统的线程池而是自己创建的线程池?

果然如此,经过搜索,发现有一个接口,调用一次就会创建一个最小线程数为10的线程池,搜了一个这个接口的调用情况,果然是在中午的时候开始高频率的调用,直至晚上8.30结束了调用,这也是调整JVM内存看似解决问题的原因。

三、结论

要慎用线程池,尽量使用公用线程池,这用线程比较可控。像我今天遇到的问题,3万个线程,每个线程配置了2M,就是60G,肯定会内存溢出的。

四、收获

这次排查问题,收获颇多,总结如下。

  • 排查利器之日志:一定要知道tomcat有哪些日志,每种日志的作用。

1、比如bin目录下的hs_err_pid*.log,这个日志记录了致命错误,比如我这次遇到的内存溢出。

2、比如catalina.out,也会记录一些错误信息。

  • 排查利器之virsualVM:至少从宏观上知道,是CPU标高,还是线程多,还是内存使用高。比如这次,从宏观上可以看到,是线程突增导致内存溢出。
  • 排查利器之tomcat请求可视化:可以一目了然知道每个请求的时间周期内的调用次数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值