1. 程式人生 > >頻繁FullGC的問題排查和解決

頻繁FullGC的問題排查和解決

一、問題排查

1.jstat -gc 【pid】檢視gc情況

2.發現FullGC過多,通過 jmap -histo 【pid】檢視堆中物件統計

二、問題解決

實際工作中,主要發現兩個資料結構相關原因會導致FULL GC

1. LinkedBlockingQueue$Node

當資料量很大時,LinkedBlockingQueue會無限制存放資料,最終導致Allocation Failure的Full GC。由下圖可知LinkedBlockingQueue的無參建構函式是一個無界佇列,所以需要使用有參建構函式併合理設定數值來限制節點數量。

          

2.執行緒池

使用Executors.newFixedThreadPool(nThreads)構造執行緒池處理訊息,結果由於訊息量很大,造成記憶體消耗過快,頻繁FULL GC,其本質原因也是佇列無限存放資料。

解決方案是構造一個阻塞的容量5000的任務佇列,且在佇列滿的時候執行CalllerRunsPolicy的拒絕策略

new ThreadPoolExecutor(nThreads, nThreads,
                30, TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<Runnable>(5000),
                new ThreadPoolExecutor.CallerRunsPolicy());