0

我有一个关于 Java 堆空间的问题。

我有一个程序,它使用地理工具从街道网络创建图表。我用它做了一些事情,但我遇到了 OutOfMemoryError 但我不确定为什么。我使用以下代码来获取可用内存量。

Runtime rt = Runtime.getRuntime();
long maxMb = rt.freeMemory()/(1024*1024);
System.out.println("Your JVM has " + maxMb + " MB of memory left");

当我运行我的程序时,似乎有足够的内存(见输出)。此控制台输出在 OutOfMemory 错误发生之前完成。那么出了什么问题呢?当我扩大 Java 堆空间时,仍然发生 OutOfMemory 错误(但还剩 1461 MB)。我不知道为什么会这样?有任何想法吗?

Your JVM has 981 MB of memory left
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.util.Arrays.copyOf(Unknown Source)
at java.util.ArrayList.grow(Unknown Source)
at java.util.ArrayList.ensureCapacityInternal(Unknown Source)
at java.util.ArrayList.add(Unknown Source)
at masterthesis.datastructures.Stroke.addStrokeSegment(Stroke.java:78)
at masterthesis.algorithms.StrokeBuilder.buildStroke(StrokeBuilder.java:145)
at org.geotools.test.Main.main(Main.java:109)
4

4 回答 4

1

以下是调试 OOM 的一种方法。

  1. 将您的最大堆大小调整为合理的大小,例如 256 MB。将其保持在合理的低水平将有助于您完成第 3 步。
  2. 将 -XX:+HeapDumpOnOutOfMemoryError 添加到命令行。这将在遇到 OOM 后转储内存。
  3. 在Eclipse Memory Analyzer中打开转储并尝试分析最大的对象。它可以生成看起来像这样的报告。

在此处输入图像描述

于 2012-11-01T16:00:19.617 回答
0

你应该使用jmap来了解你的内存是什么。

于 2012-11-01T15:52:18.260 回答
0

尝试阅读Java:OutOfMemoryError Exception 和 freeMemory()

Runtime.freeMemory() javadoc 说这是返回“当前可用于未来分配对象的内存总量的近似值”

所有动态结构的工作方式是它们以块的形式分配内存。当 HashMap 变满时,它不会再为一个对象分配额外的空间。它分配了一些大小的块。我不知道它在 JVM 中的确切工作方式,但它可能会尝试分配两倍于当前使用的内存量。

于 2012-11-01T15:52:41.923 回答
0

由于输出表明您还有大量内存,并且在数组列表增长期间发生错误,我猜测您有一个非常巨大的数组列表,您可以将对象放入其中。当 JVM 尝试增加列表时,您没有足够的内存堆空间以容纳列表大小的两倍。

我会调查您实际在列表中放入了多少对象addStrokeSegment()

于 2012-11-01T15:56:25.737 回答