本文介绍了在调用Hashmap.remove()后立即发生垃圾收集吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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 to System.gc() are ignored.

这篇关于在调用Hashmap.remove()后立即发生垃圾收集吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-18 06:47