繁体   English   中英

为什么在删除大量(〜80%)密钥后HashMap的大小没有改变?

[英]Why size of HashMap is not changing after removing large amount (~80%) of keys?

我需要使用一个HashMap,其键为Long数据类型,其值是一些用户对象,定义为:

HashMap <Long,SomeClass> dummy=new HashMap<>();

最初,该dummy哈希图包含大约1000万个<key,value>对,使用

  dummy.add(SomeLong,new SomeClass(SomeParameters);

消耗的内存为7-8GB。 创建此映射后,将删除80-90%的条目:

for (Iterator<Entry<Long, SomeClass>> it = collisionMap.entrySet().iterator(); it.hasNext();) {
    Map.Entry<Long,SomeClass> entry = it.next();         
    if(SomeCondition) {
       it.remove(); 
    }
 }  

删除这些条目后,正在使用的内存仍然相同。 我检查了Runtime.getRuntime().totalMemory()Runtime.getRuntime().freeMemory()

现在的问题是,为什么在此remove()操作之后没有回收内存? 我在编程过程中创建了大约1000-2000次这种类型的哈希图。 它给出了java.lang.OutOfMemoryError: GC overhead limit exceeded错误:(

有人可以帮忙吗? 谢谢

*****************更新/其他信息****************

SomeClass定义为:

Class SomeClass {
   private ArrayList <Integer> list1;
   private ArrayList <Integer> list2;    
   public SomeClass(int l,List <Integer> l2) {
     list2=l2;
     list1=new ArrayList<>();
     list1.add(l);
   }     
   public void addList1(int l) { list1.add(l); } 
   public ArrayList <Integer> getList1() { return list1; } 
   public ArrayList <Integer> getList2() { return list2; }    
}

由于某些原因,我早些时候计划使用BitSet数据类型而不是ArrayList list1 而且,如果我用BitSet variable and set the替换list1' by a variable and set the l bit instead of adding l to list1'中,然后使用此类的对象创建虚拟HashMap,则关于内存的结果会有所不同。 令人惊讶的是,在HashMap上执行remove操作后,将回收内存。 例如,在删除HahsMap内存中约80%的条目后,使用的内存也会减少约40%。

是否没有回收分配给ArrayList的内存? :( :(

java.lang.OutOfMemoryError:超出了GC开销限制

这表明您并不一定要占用过多的内存(尽管在您的情况下,映射可能会为其内部节点阵列消耗多达80MB的内存),但是GC的呼吸空间(最大堆限制)或CPU时间( GC时限)可根据您的分配资料进行工作。

您很可能必须调整GC参数以避免此问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM