问题描述
Java代码如下: Random r = new Random(1234697890);
HashMap<整数,列表<整数>> map = new HashMap< Integer,List< Integer>>();
列表<整数> list = new ArrayList< Integer>(); (int i = 0; i for(int j = 0; j list.add(r。 nextInt(100000));
}
map.put(i,list);
map.remove(i);
when i
达到37553, java.lang.OutOfMemoryError:Java堆空间
发生。
似乎垃圾收集不会在循环中发生。
现在我想知道如何解决这个问题。
尝试重写代码如下,你不应该得到OOME的...
Random r = new Random(1234697890);
HashMap<整数,列表<整数>> map = new HashMap< Integer,List< Integer>>();
for(int i = 0; i List< Integer> list = new ArrayList< Integer>();
for(int j = 0; j list.add(r.nextInt(100000));
}
map.put(i,list);
map.remove(i);
}
原始代码的问题在于:
- 您只能创建一个列表,
- 不断添加更多元素,并且
- 当代码完成时,该列表只会变成垃圾...因为它在整个时间范围内。
在循环中移动列表
声明意味着在每次循环迭代中创建并填充新的 ArrayList
,并且变成垃圾当你开始下一次迭代。
有人建议调用 System.gc()
。这对你的情况根本无济于事,因为收集到的垃圾最少。一般来说,这是一个坏主意,因为:
- GC保证在引发OOME之前立即运行,
- JVM的运行时间最长(即最有效)的时间可以超过您的预期,
- 调用
无论如何,System.gc()
可能完全被忽略。可以配置JVM,以便忽略对System.gc()
的调用。
- 调用
The Java code is as follows:
Random r = new Random(1234697890);
HashMap<Integer, List<Integer>> map = new HashMap<Integer, List<Integer>>();
List<Integer> list = new ArrayList<Integer>();
for(int i=0;i<100000;i++){
for(int j=0;j<1000;j++){
list.add(r.nextInt(100000));
}
map.put(i, list);
map.remove(i);
}
when i
reaches 37553 , java.lang.OutOfMemoryError: Java heap space
happens.
It seems that garbage collection does not happen in the loop.
Now I wonder how to fix the problem.
Try rewriting the code as follows and you should not get OOME's ...
Random r = new Random(1234697890);
HashMap<Integer, List<Integer>> map = new HashMap<Integer, List<Integer>>();
for(int i=0;i<100000;i++){
List<Integer> list = new ArrayList<Integer>();
for(int j=0;j<1000;j++){
list.add(r.nextInt(100000));
}
map.put(i, list);
map.remove(i);
}
The problem with your original code is that:
- you only create one list,
- you keep adding more and more elements to it, and
- that list only becomes garbage when the code completes ... because it is "in scope" the whole time.
Moving the list
declaration inside the loop means that a new ArrayList
is created and filled in each loop iteration, and becomes garbage when you start the next iteration.
Someone suggested calling System.gc()
. It won't help at all in your case because there is minimal garbage to be collected. And in general it is a bad idea because:
- the GC is guaranteed to have run immediately before an OOME is thrown,
- the JVM can figure out better than you can when is the best (i.e. most efficient) time to run the GC,
- your call to
System.gc()
may be totally ignored anyway. The JVM can be configured so that calls toSystem.gc()
are ignored.
这篇关于在调用Hashmap.remove()后立即发生垃圾收集吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!