Java堆空间内存不足

时间:2011-07-19 14:03:47

标签: java memory physics heap-memory

我的应用程序目前消耗了大量内存,因为它正在运行物理模拟。问题是始终如一,在第51次模拟时,java会抛出一个错误,通常是因为堆空间内存不足(我的程序最终运行了数千次模拟)。

无论如何我不能只增加堆空间但是修改我的程序以便在每次运行后清除堆空间以便我可以运行任意数量的模拟?

由于

-edit -

谢谢你们。事实证明,每次运行后模拟器软件都没有清除信息,我将这些运行全部存储在一个arraylist中。

9 个答案:

答案 0 :(得分:36)

由于在Java虚拟机启动时分配了堆,因此无法以编程方式动态增加堆。

但是,您可以使用此命令

java -Xmx1024M YourClass

将内存设置为1024

或者,您可以设置最小最大值

java -Xms256m -Xmx1024m YourClassNameHere

答案 1 :(得分:19)

如果您使用大量内存并面临内存泄漏,那么您可能需要检查是否使用了大量ArrayList个或HashMap个,每个元素都有很多元素。

ArrayList实施为dynamic array。 Sun / Oracle的源代码显示,当一个新元素插入一个完整的ArrayList时,会创建一个大小为原始数组1.5倍的新数组,并复制这些元素。这意味着您可能会浪费在您使用的每个ArrayList中最多50%的空间,除非您调用其trimToSize方法。或者更好的是,如果您知道要在手边插入的元素数量,那么以初始容量作为参数调用构造函数。

我没有仔细检查HashMap的源代码,但乍一看似乎每个HashMap中的数组长度必须是2的幂,这使得它成为另一个实现动态数组。请注意,HashSet本质上是HashMap的包装。

答案 2 :(得分:12)

您可以使用各种工具来帮助诊断此问题。 JDK包含JVisualVM,允许您附加到正在运行的进程并显示哪些对象可能会失控。 Netbeans有一个包装它,运行得相当好。 Eclipse有Eclipse Memory Analyzer,这是我经常使用的,只是似乎更好地处理大型转储文件。还有一个命令行选项-XX:+HeapDumpOnOutOfMemoryError,它将为您提供一个文件,该文件基本上是程序崩溃时进程内存的快照。您可以使用上面提到的任何工具来查看它,在诊断这些问题时它确实有很大的帮助。

根据程序运行的难度,可能是JVM不知道何时可以进行垃圾收集的简单情况,您也可以查看并行垃圾收集选项。

答案 3 :(得分:6)

我也遇到了同样的问题。我通过以下步骤进行构建解决了。

- >右键单击项目选择RunAs - >运行配置

选择您的项目作为BaseDirectory。代替目标给eclipse:eclipse安装

- >在第二个标签中,将-Xmx1024m作为VM参数。

答案 4 :(得分:3)

我想补充一点,这个问题类似于常见的Java内存泄漏。

当JVM垃圾收集器无法清除Java / Java EE应用程序的“浪费”内存时,OutOfMemoryError: Java heap space将成为结果。

首先进行适当的诊断非常重要:

  • 启用verbose:gc。这样您就可以了解内存增长模式。
  • 生成并分析JVM Heap Dump。这将使您了解应用程序内存占用情况并查明内存泄漏源。
  • 您还可以使用Java分析器和运行时内存泄漏分析器(如Plumbr)来帮助您完成此任务。

答案 5 :(得分:2)

尝试添加-Xmx以获得更多内存(java -Xmx1024M YourClass),并且不要忘记停止引用您不再需要的变量(内存泄漏)。

答案 6 :(得分:1)

您是否保留对不再需要的变量的引用(例如以前模拟的数据)?如果是这样,您有内存泄漏。您只需要找到发生的位置,并确保在不再需要时删除对变量的引用(如果它们超出范围,这将自动发生)。

如果您确实需要内存中先前模拟的所有数据,则需要增加堆大小或更改算法。

答案 7 :(得分:0)

当不再引用所有对象时,Java应该为您清除堆空间。它通常不会将其释放回操作系统,但它将保留内存以供其自身内部重用。也许检查一下你是否有一些没有被清除的数组。

答案 8 :(得分:0)

没有。只要有感觉,堆就会被垃圾收集器清除。您可以要求它运行(使用System.gc()),但不保证可以运行。

首先尝试通过设置-Xmx256m

来增加内存