简体   繁体   English

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

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

I need to use a HashMap whose keys are of Long datatype and values are some user-objects, defined as: 我需要使用一个HashMap,其键为Long数据类型,其值是一些用户对象,定义为:

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

Initially this dummy hashmap contains about 10 million <key,value> pairs, added using 最初,该dummy哈希图包含大约1000万个<key,value>对,使用

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

The memory consumed is 7-8GB. 消耗的内存为7-8GB。 After creating this map, 80-90% of entries are to be removed: 创建此映射后,将删除80-90%的条目:

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

The memory being used is still same after removing these entries. 删除这些条目后,正在使用的内存仍然相同。 I checked with Runtime.getRuntime().totalMemory() and Runtime.getRuntime().freeMemory() . 我检查了Runtime.getRuntime().totalMemory()Runtime.getRuntime().freeMemory()

Now the problem is why the memory has not been reclaimed after this remove() operation? 现在的问题是,为什么在此remove()操作之后没有回收内存? I am creating this type of hashmap about 1000-2000 times during the course of program. 我在编程过程中创建了大约1000-2000次这种类型的哈希图。 And it is giving java.lang.OutOfMemoryError: GC overhead limit exceeded error :( 它给出了java.lang.OutOfMemoryError: GC overhead limit exceeded错误:(

Can anyone help? 有人可以帮忙吗? Thanks 谢谢

***************** Update/Additional information **************** *****************更新/其他信息****************

The SomeClass is defined as: 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; }    
}

For some reasons, I had earlier planned to use BitSet datatype instead of ArrayList list1 . 由于某些原因,我早些时候计划使用BitSet数据类型而不是ArrayList list1 And if I replace list1' by a BitSet variable and set the l^th bit instead of adding l to list1' and then create dummy HashMap with the objects of this class, then the results about memory are different. 而且,如果我用BitSet variable and set the替换list1' by a variable and set the l bit instead of adding l to list1'中,然后使用此类的对象创建虚拟HashMap,则关于内存的结果会有所不同。 Surprisingly, the memory is reclaimed after remove operation on HashMap. 令人惊讶的是,在HashMap上执行remove操作后,将回收内存。 Eg After removing about 80% of entries in HahsMap memory being used is also reduced by 40% approx. 例如,在删除HahsMap内存中约80%的条目后,使用的内存也会减少约40%。

Is it that memory allocated to an ArrayList is not being reclaimed? 是否没有回收分配给ArrayList的内存? :( :( :( :(

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

This indicates that you're not necessarily using up too much memory (although the map may consume up to 80MB for its internal nodes array in your situation) but that the GC does not have enough breathing room (max heap limit) or CPU time (GC time limit) available to do its work given your allocation profile. 这表明您并不一定要占用过多的内存(尽管在您的情况下,映射可能会为其内部节点阵列消耗多达80MB的内存),但是GC的呼吸空间(最大堆限制)或CPU时间( GC时限)可根据您的分配资料进行工作。

You most likely have to tune your GC parameters to avoid this issue. 您很可能必须调整GC参数以避免此问题。

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

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