我的应用程序目前消耗了大量内存,因为它正在运行物理模拟。问题是始终如一,在第51次模拟时,java会抛出一个错误,通常是因为堆空间内存不足(我的程序最终运行了数千次模拟)。
无论如何我不能只增加堆空间但是修改我的程序以便在每次运行后清除堆空间以便我可以运行任意数量的模拟?
由于
-edit -
谢谢你们。事实证明,每次运行后模拟器软件都没有清除信息,我将这些运行全部存储在一个arraylist中。
答案 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将成为结果。
首先进行适当的诊断非常重要:
答案 5 :(得分:2)
尝试添加-Xmx以获得更多内存(java -Xmx1024M YourClass
),并且不要忘记停止引用您不再需要的变量(内存泄漏)。
答案 6 :(得分:1)
您是否保留对不再需要的变量的引用(例如以前模拟的数据)?如果是这样,您有内存泄漏。您只需要找到发生的位置,并确保在不再需要时删除对变量的引用(如果它们超出范围,这将自动发生)。
如果您确实需要内存中先前模拟的所有数据,则需要增加堆大小或更改算法。
答案 7 :(得分:0)
当不再引用所有对象时,Java应该为您清除堆空间。它通常不会将其释放回操作系统,但它将保留内存以供其自身内部重用。也许检查一下你是否有一些没有被清除的数组。
答案 8 :(得分:0)
没有。只要有感觉,堆就会被垃圾收集器清除。您可以要求它运行(使用System.gc()
),但不保证可以运行。
首先尝试通过设置-Xmx256m