集合未分页处理导致的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文件。

posted on 2018-12-05 11:58  coderDu  阅读(286)  评论(0编辑  收藏  举报