11回复
5年前
ArrayList扩容内存无法回收问题
学习你假笨公众号的一篇文章假笨说-又抓了一个导致频繁GC的鬼–数组动态扩容 的问题,自己实验了一下,现象如下:
- allocate()方法执行完成后,频繁CMS GC,但是old区仍然占用大,基本未回收空间
2.添加-XX:+CMSScavengeBeforeRemark参数,remark之前的一次ygc也未回收空间,old情况同1 - 若MyArraylist初始化容量为它需要add的数量,则不存在上述现象
此处还存在几个问题:
- 在allocate()方法执行完后在Jprofiler中查看存活对象MyArraylist已经没有,按照文中的解释应该是新扩容的数组在young区,old区已满ygc没有正常进行导致,既然list对象都不存活了为什么新扩容的数组还在呢?
- 另外想请教下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);
}
}
5174 阅读