Java:OutOfMemoryError异常和freeMemory()

use*_*813 6 java memory exception out-of-memory

我有以下测试程序:

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我运行这个程序,我得到以下输出:

...

    ############
    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)
Run Code Online (Sandbox Code Playgroud)

为什么我得到一个"OutOfMemoryError"异常,虽然freeMemory()方法返回有更多的空闲内存??? 如果有办法使用所有freeMemory()?

Gra*_*ray 5

HashMap该类有时会随着条目数的增加而调整大小。即使您显示有300 + K的剩余空间,也可能不足以处理哈希存储桶的大小调整。

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);
}
Run Code Online (Sandbox Code Playgroud)

从更一般的意义上讲,在Java中不建议对堆内存(和整个进程大小)进行细粒度的期望。后台回收以及堆中尚未回收的对象占用了您可能无法预期的空间。另外,垃圾收集器在接近满堆时会逐渐使用越来越多的CPU。您想以超出预期最大分配大小的大量内存开销运行。


Upu*_*ara 0

似乎可用内存量不足以运行 JVM。