【问题标题】:Java System.GC() and Memory LeakageJava System.GC() 和内存泄漏
【发布时间】:2014-01-21 00:48:04
【问题描述】:

我已经阅读并搜索了有关泄漏内存和逐渐增加 RAM 的论坛。我尝试在我的程序中每 60 秒使用一次 System.GC() 方法的调用,并且考虑到我的 RAM 使用量每次调用都会下降,它似乎正在工作。为什么不使用这种方法是个好主意?在我读过的每一篇文章中,他们似乎都含糊地解释了为什么该方法不能释放内存,但我的程序似乎另有说明。有些人甚至说该方法根本没有做任何事情,只是建议垃圾收集器清理自己。注意:我的泄漏不是来自我知道的静态方法,因为我从整个项目中删除了它们并且 RAM 仍然增加了。我会发布我的代码,但它相当大,所以我怀疑是否有人愿意阅读它。

感谢您的帮助。

【问题讨论】:

  • 你并没有真正保存任何调用 GC 的东西。当堆填满时,将触发 GC,并没有真正的优势(但有 执行成本)导致它更快发生。
  • 要明白,每次你创建一个要在打印语句中使用的字符串时,你(在某种程度上)“泄漏”了该字符串的存储空间,因为它不会立即“回收”你已经完成了。不过没关系,因为 GC 会找到这些未使用的对象并为您回收存储。但这不需要立即发生 - 与等待“正常”触发 GC 相比,提前恢复存储没有任何优势。
  • @Hot Licks 好的,我现在明白了。默认情况下仅打印出信息会增加内存使用量,调用 GC 方法会清理用于此目的的 RAM。那么我该如何解决这个明显的泄漏问题。我删除了所有的静力学,但没有重大变化。我有大量使用计时器的 actionListener 可能是问题所在?
  • 什么“明显的泄漏问题”?到目前为止,您还没有描述过一个。
  • @Hot Licks 当我运行程序时,我以图形方式打印出的内存使用量一直在逐渐增加,除非我使用 GC 方法。

标签: java memory-leaks garbage-collection


【解决方案1】:

正如您所说,System.gc() 只是一个建议。不能保证强制进行垃圾收集,但实际上它经常这样做。

Java 垃圾收集定期自行运行。如果你发现你的内存随着时间的推移而增加并且你没有回收它,那么你就有了内存泄漏。调用 System.gc() 不会解决这个问题。如果您的内存泄漏,最终将没有什么可收集的。

一般来说,您不需要强制 GC。正如我所提到的,GC 将自行运行。您可以调整其行为 - http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html

【讨论】:

  • 次要问题:如果您看到在 GC 运行后立即占用的存储量随着时间的推移而增加,那么您有(某种)“泄漏”。 GC 之间占用的存储空间增加是完全正常的。
  • @Jeff Storey 谢谢你的信息。泄漏可能是由于我无法控制的事情,还是我只是做了任何可能导致这种情况发生的特别事情?
  • 取决于 - 它可能来自任何一个。当您的应用程序运行时,内存使用量增加是正常的,但是您是否看到内存不断增加到您用完的地步?我真正要问的是 - 你确定你有泄漏吗?
  • 从打印出我的程序的 ram 使用情况来看,“虽然它可能需要很长时间”,但程序运行每秒增加约 0.5%。我不知道是我简单地将 RAM 使用情况打印出来还是其他原因。加班我发现这可能是一个问题,因为一直存在 OutOfMemoryException。
  • @Jeff Storey 当我调用 GC 方法时,它确实会增加,但只会增加 0.00001%。这是否意味着我真的没有合法的泄漏?
【解决方案2】:

最初的问题来自内存泄漏。 症状是 * 因为内存泄漏,没有足够的内存空间 * 所以JVM会再次尝试再次进行GC。 * 但仍有足够的内存。所以再次GC。

所以 System.GC 或某种 GC 调整没有帮助。

要解决这个问题,你必须找到我们的内存泄漏点。

在 JVM 中,有一些工具可以转储当前的内存占用 (heapdump)。

您可以使用它找出泄漏点。 欲了解更多信息,请参阅 - http://www.oracle.com/technetwork/java/javase/memleaks-137499.html

【讨论】:

  • 感谢您的文章,我会收藏它。非常有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-29
  • 2015-08-14
  • 2012-08-11
  • 2015-12-14
  • 1970-01-01
相关资源
最近更新 更多