Java堆内存

时间:2012-11-01 15:48:54

标签: java memory heap

我对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 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

你应该使用jmap来了解你的记忆力。

答案 2 :(得分:0)

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

  

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

     

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

答案 3 :(得分:0)

由于输出表明你有大量的内存并且在数组列表增长期间出现错误,我的猜测是你有一个非常庞大的arraylist,你把对象放进去。当JVM尝试增长列表你做的时候没有足够的堆空间来容纳列表大小加倍。

我会使用addStrokeSegment()调查您实际放入列表中的对象数量。