Java堆空间内存不足
我的应用程序目前消耗相当多的内存,因为它正在运行物理模拟。 问题在于,在第五十一次模拟中,java通常会因为内存空间不足而抛出一个错误(我的程序最终会运行数千次模拟)。
有没有反正我不能只增加堆空间,但修改我的程序,以便在每次运行后清空堆空间,以便我可以运行任意数量的模拟?
谢谢
-编辑-
多谢你们。 事实certificate,模拟器软件在每次运行后都没有清除信息,并且我将这些运行全部存储在数组列表中。
由于Java虚拟机启动时分配了堆,因此无法以编程方式dynamic增加堆。
但是,您可以使用此命令
java -Xmx1024M YourClass
将内存设置为1024
或者,您可以设置最小最大值
java -Xms256m -Xmx1024m YourClassNameHere
如果你正在使用大量的内存,并面临内存泄漏,那么你可能要检查你是否使用了大量的ArrayList
或HashMap
,每个都有很多元素。
一个ArrayList
被实现为一个dynamic数组 。 来自Sun / Oracle的源代码显示,当一个新元素被插入一个完整的ArrayList
,将创build一个1.5倍于原始数组大小的新数组,并将元素复制过来。 这意味着,除非您调用trimToSize
方法,否则可能会浪费多达使用的每个ArrayList
50%的空间。 或者更好的是,如果你知道你将要插入的元素的数量,然后以初始容量作为参数调用构造函数。
我没有仔细检查HashMap
的源代码,但乍看之下,每个HashMap
中的数组长度必须是2的幂,使得它成为dynamic数组的另一个实现。 请注意, HashSet
本质上是一个HashMap
的包装。
有很多工具可以用来帮助诊断这个问题。 JDK包含JVisualVM ,它将允许您附加到正在运行的进程,并显示哪些对象可能失去控制。 Netbeans有一个很好的包装。 Eclipse具有最常用的Eclipse内存分析器,似乎可以更好地处理大型转储文件。 还有一个命令行选项-XX:+ HeapDumpOnOutOfMemoryError ,当程序崩溃时,它会给你一个基本上是进程内存快照的文件。 你可以使用上面提到的任何工具来查看它,在诊断这些问题时它确实可以帮助很多。
根据程序工作的难易程度,可能是JVM不知道什么时候垃圾收集可能是一个简单的情况,也可以查看并行垃圾收集选项。
我也面临同样的问题。我通过按照以下步骤进行构build来解决问题。
– >右键单击项目selectRunAs – >运行configuration
select您的项目作为BaseDirectory。 代替目标给eclipse:eclipse安装
– >在第二个选项卡中给-Xmx1024m作为VM参数。
我想补充一点,这个问题是类似于普通的Java内存泄漏。
当JVM垃圾收集器无法清除Java / Java EE应用程序的“浪费”内存时, OutOfMemoryError:Java堆空间将成为结果。
首先执行正确的诊断很重要:
- 启用详细:gc 。 这将使您了解随着时间的推移内存增长模式。
- 生成并分析JVM堆转储 。 这将允许您了解您的应用程序内存占用并查明内存泄漏的来源。
- 您也可以使用Java分析器和运行时内存泄漏分析器(如Plumbr)来帮助您完成此任务。
尝试添加-Xmx以获取更多内存( java -Xmx1024M YourClass
),并且不要忘记停止引用不再需要的variables(内存泄漏)。
你是否保持对不再需要的variables的引用(例如,来自之前仿真的数据)? 如果是这样,你有一个内存泄漏。 你只需要find发生的地方,并确保你不再需要的时候删除对variables的引用(如果它们超出范围,这将自动发生)。
如果实际上需要在内存中使用以前模拟的所有数据,则需要增加堆大小或更改algorithm。
当所有对象不再被引用时,Java应该为你清除堆空间。 它通常不会将其释放回操作系统,但会保留该内存以供内部重用。 也许检查是否有一些数组没有被清除或什么的。
没有。垃圾收集器每当感觉到它就清除堆。 你可以让它运行(使用System.gc()
),但不能保证运行。
首先尝试通过设置-Xmx256m
增加内存