Java: OutOfMemoryError Exception and freeMemory()

假装没事ソ 提交于 2019-12-08 20:35:16

问题


I have the following test program:

public static void main(String[] args)
{       
    HashMap<Integer, String> hm = new HashMap<Integer,String>(); 
    int i = 1;  
    while(true)
    {
        hm.put(i, "blah");
        i++;
        System.out.println("############"); 
        System.out.println("Max mem: " + Runtime.getRuntime().maxMemory()); 
        System.out.println("Total mem: " + Runtime.getRuntime().totalMemory()); 
        System.out.println("Free mem:" + Runtime.getRuntime().freeMemory());
    }
}

If I run this program, I get the follwing output:

...

    ############
    Max mem: 8060928

    Total mem: 8060928

    Free mem:334400

    Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
        at java.util.HashMap.addEntry(Unknown Source)
        at java.util.HashMap.put(Unknown Source)
        at Test.main(Test.java:14)

Why I get an "OutOfMemoryError" Exception although the method freeMemory() returns that there is more free memory??? If there a way to use all the freeMemory()?


回答1:


The HashMap class resizes on occasion as the number of entries in it grows. Even though you are showing 300+K left free, that may not be enough to handle the resizing of the hash buckets.

void resize(int newCapacity) {
    Entry[] oldTable = table;
    int oldCapacity = oldTable.length;
    if (oldCapacity == MAXIMUM_CAPACITY) {
        threshold = Integer.MAX_VALUE;
        return;
    }
    // ***possible big allocation here***
    Entry[] newTable = new Entry[newCapacity];
    transfer(newTable);
    table = newTable;
    threshold = (int)(newCapacity * loadFactor);
}

In a more general sense, fine grained expectations over the heap memory (and overall process size) is not recommended in Java. There are background allocations as well as objects in the heap that have yet to be reclaimed that take up space that you may not have anticipated. In addition, the garbage collector uses progressively more and more CPU as it approaches a full heap. You want to run with plenty of memory overhead above your expected maximum allocation size.




回答2:


  1. Runtime.freeMemory() javadoc says that is returns "an approximation to the total amount of memory currently available for future allocated objects"

  2. The way all dynamic structures work is that they allocate memory in chunks. When HashMap is getting full it doesn't allocate extra space for just one more object. It allocates a chunk of some size. I do not know the exact way it works in JVM, but it may try to allocate as much as twice the amount of current memory it uses.




回答3:


You will be getting the out of memory exception at the point where the HashMap need to expand it's internal storage. The requirement for this will be greater than the available feel memory.




回答4:


It seems like amount of free memory is not enough to run the JVM.



来源:https://stackoverflow.com/questions/8183343/java-outofmemoryerror-exception-and-freememory

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!