性能问答>ArrayList扩容内存无法回收问题>
11回复
4年前

ArrayList扩容内存无法回收问题



学习你假笨公众号的一篇文章假笨说-又抓了一个导致频繁GC的鬼–数组动态扩容 的问题,自己实验了一下,现象如下:

  1. allocate()方法执行完成后,频繁CMS GC,但是old区仍然占用大,基本未回收空间
    2.添加-XX:+CMSScavengeBeforeRemark参数,remark之前的一次ygc也未回收空间,old情况同1
  2. 若MyArraylist初始化容量为它需要add的数量,则不存在上述现象

此处还存在几个问题

  1. 在allocate()方法执行完后在Jprofiler中查看存活对象MyArraylist已经没有,按照文中的解释应该是新扩容的数组在young区,old区已满ygc没有正常进行导致,既然list对象都不存活了为什么新扩容的数组还在呢?
  2. 另外想请教下dump文件怎么查看对象目前所属的分代

附实验代码如下:

// jdk1.7  -Xmx500M -Xms500M -Xmn200M -XX:+UseConcMarkSweepGC
    // -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=90
    private static int unit = 20 * 1024;

    public static void main(String[] args) throws Exception{
        Thread.sleep(5000);
        System.out.println("allocate start************");
        allocate();


        Thread.sleep(1000);
        System.out.println("allocate end************");
        Thread.sleep(120000);
    }

    private static void allocate() throws Exception{
        List<BigObject> list = new MyArrayList<>();
        int size = 1024 * 1024 * 400; // 400M
        int len = size / unit;

        for( int i = 0; i < len; i++){

            BigObject bigObject = new BigObject();
            list.add(bigObject);
            Thread.sleep(3);
        }
    }

    private static class BigObject{
        private byte[] foo;

        BigObject(){
            foo = new byte[unit];
        }
    }

    private static class MyArrayList<E> extends ArrayList<E>{
        public MyArrayList() {
            super();
        }

        public MyArrayList(int initialCapacity){
            super(initialCapacity);
        }
    }
5159 阅读
请先登录,查看11条精彩评论吧
快去登录吧,你将获得
  • 浏览更多精彩评论
  • 和开发者讨论交流,共同进步