Java:独立运行之间清除内存

时间:2015-01-30 17:24:04

标签: java loops garbage-collection out-of-memory

我在Java中实现了一种启发式解决方案,解决了给定输入的优化问题。启发式算法可以运行数千次迭代,并创建大量不同复杂度的对象。

为了测试它,我有成千上万的测试输入。我的main方法接受所有输入,并按顺序为循环中的每个输入启动启发式。结果存储在每个输入的单独文件中。

当我运行程序时,它总是在生成218或219后停止并抛出" OutOfMemoryError"。一旦它显示Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceededException in thread "main" java.lang.OutOfMemoryError: Java heap space

我的猜测是,程序会随着时间的推移创建太多的对象,直到计算第218或第219个输入时内存不足。每个实例都是在独立运行中计算的。因此,它应该解决问题,在存储输入结果之后和解析下一个输入之前清除内存并清除所有创建的对象。那是对的吗?我听说使用System.gc()是不好的做法,但在我的案例中你会推荐什么?

修改: 指定我想要的东西:而不是按"开始"对于每个输入,我实现了循环来为我做这个。但是,似乎它的行为方式并不相同,并且它保留了之前运行的旧对象。我可以改变我的java代码,使其行为类似于为每个输入重新启动程序吗?或者我是否必须使用shell skript分别为每个输入启动我的启发式以使其工作? 我从来没有使用任何JVM参数,在我看来他们并没有真正解决这个问题。

已解决:事实上我发现并修复了内存泄漏。不需要System.gc()。谢谢你的帮助!

3 个答案:

答案 0 :(得分:0)

是使用JVM进行GC处理。您需要按顺序执行以下一些步骤:

  • 使用Xmx ...参数
  • 增加堆大小
  • 设置正确的GC算法和参数。如果您已有GC参数,请尝试调整parameters
  • 尝试使用-XX:+ HeapDumpOnOutOfMemoryError和-XX:HeapDumpPath =<堆转储路径>启动JVM时的选项,以便在jvm运行OOM时获得堆转储。通过使用堆转储,您可以使用jprofiler / yourkit / jvisualvm等分析器来调查内存泄漏,然后纠正它们。

答案 1 :(得分:0)

首先,当您启动JVM来运行测试时,请禁用GC开销限制:

-XX:-UseGCOverheadLimit

我推荐这个,因为你已经知道你故意强调垃圾收集器,并且你不希望它警告你GC的开销。

第二次,看一看如何更好地分解测试,以便允许对前一个测试中的对象进行垃圾回收。在每次测试完成后,不要将活动指针保持为大型对象结构。

第三次,如果由于超过Java heap space仍需要更多内存,请使用:

-Xms<size>        set initial Java heap size
-Xmx<size>        set maximum Java heap size

如果你知道你将无论如何使用内存,最好将这两个设置为相同的值,以防止在执行期间发生颠簸。

不要打扰显式调用System.gc(),它最终毫无意义,因为垃圾收集总是在必要时发生。

Fourth ,另一个JVM设置,可能对您的情况有用:

-XX:NewRatio=<n>   Ratio of old/new generation sizes. The default value is 2.

通常不建议将其设置为2(2/3岁,1/3新),但在您的情况下,我建议您尝试将其设置为1(1/2旧,1/2新)。

另请参阅GC overhead limit exceeded并查看Java HotSpot VM Options

答案 2 :(得分:0)

尝试一下: http://javaandroidandrest.blogspot.de/2012/06/wait-for-jvm-garbage-collector.html

来自网站:

  

使用System.gc()等函数;或Runtime.getRuntime()。gc();只向JVM建议您要运行垃圾收集器。   我在互联网上找到了一种方法,不是强迫垃圾收集器,而是等到垃圾收集器运行。