背景:
oom的項目是在一次上線后發(fā)生過兩次宕機
使用到的工具 :
mat?
查找問題的過程
1:發(fā)生第一次宕機后,沒發(fā)現(xiàn)有問題,于是重啟了項目,添加了-XX:+HeapDumpOnOutOfMemoryError
2:過了幾天后又發(fā)生了這個問題 ,由于上次添加的命令,生成了dump文件
3:使用mat分析dump文件
4:導(dǎo)入后首先看到overview

overview
通過這個圖我們可以看出ThreadPoolExecutor占用了956M的內(nèi)存
由此可以看出應(yīng)該是線程池出了問題?
5:然后點擊查看 dominator tree?

dominator tree
通過該視圖可以看出每個對象與其引用的關(guān)系的樹狀結(jié)構(gòu),同時包含了占用堆存的大小和百分比
6:然后右鍵 選擇? list objects? -> with incoming references

通過這個圖可以看出是 utils下的 MessageSender 出的問題
找到這里再去看代碼就方便了,直接找到對應(yīng)的類,然后發(fā)送發(fā)送方法

可以看到每一次發(fā)送都會生成一個task 放到線程池里面去執(zhí)行,看到這塊沒問題
然后接著看線程池的生成

問題就在紅框這個地方了,可以看到拒絕策略這里,由于消費端消費能力過低,導(dǎo)致阻塞隊列唄塞滿,后續(xù)的觸發(fā)了拒絕策略,而這塊代碼可以看出 ,拒絕后調(diào)用了? blockingQueue.put()方法,該方法會在容量滿了以后進行阻塞,久而久之堆積的對象越來越多,導(dǎo)致oom
由于我們這個發(fā)送的是日志,有些類型的日志是不需要的
解決方法:
1:過濾掉不需要的日志,減少發(fā)送量
2:消費端優(yōu)化代碼,增加機器,提高消費能力
3:修改拒絕策略,保證不會因為消費慢而宕機