15

我的应用程序有很多迭代。到目前为止,我还没有遇到任何内存问题。但是从代码级别我可以怀疑很少有地方会导致内存泄漏和内存不足的问题。我正在考虑手动调用垃圾收集器。手动调用垃圾收集器是一种好习惯吗?

4

6 回答 6

34

您可以使用以下方式调用垃圾收集器:

System.gc();

但这并不意味着它会立即执行。JVM 决定何时执行它。一般来说,如果 JVM 即将抛出OutOfMemoryError,调用System.gc()不会阻止它。更好地调查为什么你泄漏了这么多内存并一路清理它。

Java文档

调用 gc 方法表明 Java 虚拟机花费精力回收未使用的对象,以使它们当前占用的内存可用于快速重用。当控制从方法调用返回时,Java 虚拟机已尽最大努力从所有丢弃的对象中回收空间

于 2013-03-26T08:48:40.173 回答
8

手动调用垃圾收集器是一种好习惯吗?

不,这绝对不是好习惯。

您可以使用System.gc(). 请注意,这并不能保证调用垃圾收集器 - 它只会向系统提示进行垃圾收集可能是一个好主意。

Oracle JVM 中的垃圾收集器包含许多复杂的逻辑来确定何时清理以及清理什么。调整它需要有关其工作原理的详细信息。仅仅在你的程序中放一个System.gc()地方不太可能有很大帮助,事实上,它甚至会使情况变得更糟。

有关如何使用 Java SE 6 调整垃圾收集的详细信息,请参阅Java SE 6 HotSpot Virtual Machine Garbage Collection Tuning 。

于 2013-03-26T08:51:05.310 回答
7

是的,您可以使用显式调用垃圾收集器

System.gc();

但是发生的情况是您不能命令 JVM 立即进行垃圾收集。JVM 自行决定何时进行垃圾收集。因此手动调用它不是一个好主意。

此外,关于OutOfMemoryException进行手动垃圾收集不会帮助您防止异常,因为 JVM 在回收它可以回收的所有内存后抛出此异常。它有一些非常复杂的算法来确定何时以及如何执行垃圾收集。所以我的建议是,如果你得到了OutOfMemoryException然后重新检查你的程序,使其更高效或增加堆空间。

于 2013-03-26T09:01:09.853 回答
6

您可以显式调用垃圾收集器,但 JVM 决定是否处理该调用。理想情况下,您永远不应该编写依赖于垃圾收集器调用的代码。

JVM 在内部使用一些算法来决定何时进行此调用。当您使用System.gc() 进行调用时,它只是对 JVM 的请求,而 JVM 可以随时决定忽略它。

于 2013-03-26T08:57:20.977 回答
3

不管你是否可以手动触发垃圾收集器(以及不同级别的收集),以及这对性能有什么影响(这确实是一个值得讨论的话题),它都不会阻止 OutOfMemoryErrors,因为当 JVM 大约为了耗尽内存,它无论如何都会进行最彻底的收集。只有在该集合之后没有足够的内存可用时,它才会出错。即使您自己提前触发了收集,结果(回收的内存量)也是一样的。

更频繁地运行垃圾收集无法修复内存泄漏。

它们必须在你的程序中修复(停止引用你不再需要的东西),或者(最坏的情况,如果它是“真正的”泄漏)在 JVM 或运行时库本身中(但真正的内存管理错误不应该经过这么多年的服务不再存在)。

于 2013-03-26T08:55:10.400 回答
2

调用 System.gc() 不保证任何 GC。如果确实需要内存,则会收集垃圾。
您可以在这里查看不同的垃圾收集器。
http://javarevisited.blogspot.in/2011/04/garbage-collection-in-java.html

您可以根据需要在命令行参数中包含任何这些 GC。

于 2013-03-26T08:56:14.637 回答