1. 程式人生 > >集合未分頁處理導致的full-gc

集合未分頁處理導致的full-gc

參考文獻

1. 問題

集合持有的x物件不能被young-gc,從而晉升到old區導致full-gc。因此可以設定閾值在年輕代佔滿之前釋放掉x物件——可被young-gc掉。

  • 錯誤程式碼
for(int i=0;i<bigNum;i++){
    List<ObjectX> globalList = ArrayList();
    for(int j=0;j<bigNumber;j++){
        ObjectX obj=new ObjectX();
        globalList.add(obj);
    }
    //處理連結串列物件資料
    dealWithList(golbalList);
}
  • 如果bigNumberbigNum夠大,會導致globalList持有過多的物件引用——這些物件對不能被gc回收,發生以下情況會導致頻繁的full-gc物件過多、年輕帶被佔滿,未達到年齡的物件不斷晉升到老年代,老年代被佔用到一定比例時會發生頻繁的full-gc如果每一次外迴圈globalList持有的物件太多則會直接導致記憶體溢位。
2.解決辦法

將程式碼修改為:

int thresHold=500;
for(int i=0;i<bigNum;i++){
    List<ObjectX> objList = ArrayList();
    for(int j=0;j<bigNumber;j++){
        ObjectX obj=new ObjectX();
        objList.add(obj);
        /**
         *此時年輕代已經存有thresHold*n個物件,
         *為防止年輕代被佔滿,應該及時處理物件,並清理連結串列中
         *物件引用,讓這些物件可以被young-gc掉
         */
        if(objList.size()>thresHold){
            dealWithList(golbalList);
            objList.clear();
        }
    }
    //處理連結串列物件資料
    dealWithList(golbalList);
}
3. 其他:分析問題可能用到的命令和工具
//為了儘快復原問題可以設定以下引數
-Xmx400m:最大堆記憶體;
-Xms400m:初始化堆記憶體;
-Xmn150m:年輕代大小;
-verbose:gc:verbose.a冗長的;輸出GC詳情;
-XX:+PrintGCDetails:輸出GC資訊;

-XX:+HeapDumpBeforeFullGC:在Full gc之前dump堆檔案
  • jstat -gcutil vmId x_millionSecond實時列印記憶體區佔用情況;
  • visualVM:可用於分析dump檔案。