记一次oom

背景:

oom的项目是在一次上线后发生过两次宕机

使用到的工具 :

mat 

查找问题的过程

1:发生第一次宕机后,没发现有问题,于是重启了项目,添加了-XX:+HeapDumpOnOutOfMemoryError

2:过了几天后又发生了这个问题 ,由于上次添加的命令,生成了dump文件

3:使用mat分析dump文件

4:导入后首先看到overview

overview

通过这个图我们可以看出ThreadPoolExecutor占用了956M的内存

由此可以看出应该是线程池出了问题 

5:然后点击查看 dominator tree 

dominator tree

通过该视图可以看出每个对象与其引用的关系的树状结构,同时包含了占用堆存的大小和百分比

6:然后右键 选择  list objects  -> with incoming references

通过这个图可以看出是 utils下的 MessageSender 出的问题

找到这里再去看代码就方便了,直接找到对应的类,然后发送发送方法

可以看到每一次发送都会生成一个task 放到线程池里面去执行,看到这块没问题

然后接着看线程池的生成

问题就在红框这个地方了,可以看到拒绝策略这里,由于消费端消费能力过低,导致阻塞队列呗塞满,后续的触发了拒绝策略,而这块代码可以看出 ,拒绝后调用了  blockingQueue.put()方法,该方法会在容量满了以后进行阻塞,久而久之堆积的对象越来越多,导致oom

由于我们这个发送的是日志,有些类型的日志是不需要的

解决方法:

1:过滤掉不需要的日志,减少发送量

2:消费端优化代码,增加机器,提高消费能力

3:修改拒绝策略,保证不会因为消费慢而宕机

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。