为什么在将 50,000 个对象插入 HashMap 时会出现 OutOfMemoryError?

2022-09-03 16:56:45

我正在尝试将大约50,000个对象(因此是50,000个键)插入到.但是,我不断收到一个 OutOfMemory 异常。(是我自己的类 - 非常轻的重量 - 一个字段和3个字段)。java.util.HashMap<java.awt.Point, Segment>SegmentStringint

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.HashMap.resize(HashMap.java:508)
    at java.util.HashMap.addEntry(HashMap.java:799)
    at java.util.HashMap.put(HashMap.java:431)
    at bus.tools.UpdateMap.putSegment(UpdateMap.java:168)

这似乎很荒谬,因为我看到机器上有足够的内存可用 - 无论是在可用RAM中还是在虚拟内存的HD空间中。

Java是否有可能在一些严格的内存要求下运行?我可以增加这些吗?

有没有一些奇怪的限制?我必须实现我自己的吗?还有其他值得一看的课程吗?HashMap

(我在具有 2GB RAM 的 Intel 机器上运行 OS X 10.5 下的 Java 5。


答案 1

您可以通过将 -Xmx128m(其中 128 是兆字节数)传递给 java 来增加最大堆大小。我不记得默认大小,但它让我感到震惊,它是相当小的东西。

可以使用运行时类以编程方式检查有多少内存可用。

// Get current size of heap in bytes
long heapSize = Runtime.getRuntime().totalMemory();

// Get maximum size of heap in bytes. The heap cannot grow beyond this size.
// Any attempt will result in an OutOfMemoryException.
long heapMaxSize = Runtime.getRuntime().maxMemory();

// Get amount of free memory within the heap in bytes. This size will increase
// after garbage collection and decrease as new objects are created.
long heapFreeSize = Runtime.getRuntime().freeMemory();

(示例来自 Java Developers Almanac)

这在有关 Java HotSpot VM 的常见问题和 Java 6 GC Tuning 页面中也有部分解决。


答案 2

有些人建议更改HashMap的参数以收紧内存要求。我建议测量而不是猜测;它可能是导致OOME的其他东西。特别是,我建议使用NetBeans ProfilerVisualVM(Java 6附带,但我看到你被困在Java 5中)。