显式调用System.gc()?

据说我们不能强制java中的garbage collection过程。
毕竟,它是一个守护程序线程。

但有时候,为什么我们称之为System.gc( ); function明确?
值得一试吗? 任何Pro和Con的?
如果在许多情况下没用,为什么不推荐使用Java这个方法呢?

PS:用例子说明会很有用

在我看来,最好的方法是考虑System.gc()方法,作为垃圾收集应该运行的VM的“提示”。 也就是说,就像很多人认为他们正在表现的“优化”一样,通常最好让系统自己处理事情。 系统正在发展等等等。还有一些实例,开发人员可能实际上知道更好,它的用例可能非常类似于为什么一些代码仍然用汇编编写(大多数时候,编译器更好) ,但在少数情况下 – 或者与一些开发人员 – 人类实际上可以编写更有效的代码)。

我见过的一个例子就是为了certificate它存在的合理性,如果分配了大量的对象,并且你作为开发人员知道它们不再被使用的瞬间。 在这种情况下,您可能有比GC更多的内存利用率信息(或者至少在它实现之前),并且由于回收的内存量很大,因此建议它运行是有意义的。

你回答了一半问题:值得吗? 不,因为你不能强迫它。

运行垃圾收集器。 调用此方法表明Java虚拟机花费了大量精力来回收未使用的对象,以使其当前占用的内存可用于快速重用。

这几乎是EULA-English,“你可以尝试,但我们都知道结果”。 🙂

此外,应用程序服务器可以(通常会)使用-XX:-DisableExplicitGC命令行选项禁用它。

那么重点是什么呢? 好吧,可能有一个:一些应用程序喜欢显示堆上可用的可用内存量,并且在刷新显示之前,调用System.gc();可能是适度有用的System.gc(); 在它之前。

问:为什么我们称之为System.gc(); function明确?

答:因为有人写错了代码。

我想大多数人会同意你不应该明确地调用System.gc()

让系统按照预期管理内存。 任何依赖于性能的代码很可能都会被破坏。 另外,请记住,JVM可以完全忽略您的请求。

如果您想了解更多信息,我建议您阅读以下答案:

java – 为什么调用System.gc是不好的做法?

在某些情况下,调用System.gc()很有用:

  • 您将运行一些基准测试,因此您需要以明确定义的状态开始。
  • 你期待一些重负荷,并希望尽可能做好准备。
  • 您有多个服务器,并希望通过像这里定期安排GC来避免暂停。

可能会有更多的用例,但是,您可能很快就会发现它并不需要。 大多数时候,让它以自己的方式开展工作会更好。

不打算回答这个问题,明确地调用垃圾收集器是一个糟糕的坏习惯,但是java中的一些代码确实依赖于最终化……并试图强制执行它。 在某些性能分析方案中调用它也很有用。 没有标准JVM忽略System.gc()。 当然,它可以被禁用。 但是,b / c在内存中垃圾收集器管理对外部资源的Java引用,可能需要它。

这是java.nio.Bits中的一些代码

 static void reserveMemory(long size) { synchronized (Bits.class) { if (!memoryLimitSet && VM.isBooted()) { maxMemory = VM.maxDirectMemory(); memoryLimitSet = true; } if (size <= maxMemory - reservedMemory) { reservedMemory += size; return; } } System.gc(); try { Thread.sleep(100); } catch (InterruptedException x) { // Restore interrupt status Thread.currentThread().interrupt(); } synchronized (Bits.class) { if (reservedMemory + size > maxMemory) throw new OutOfMemoryError("Direct buffer memory"); reservedMemory += size; } 

最终实际运行(或尝试运行)必须进行hibernate,清理器通常在高优先级终结器线程上进行快速跟踪。

我们在这里谈论的是什么版本的Java? 在6,我从来没有明确地称它。 作为一般的经验法则,垃圾收集器足以知道什么时候最好清理资源,并且它有足够的可配置VM选项。 我当然从来没有觉得有必要在代码中调用它,我会说除非你做的事情非常奇怪(或显示资源使用),否则最好不要。 如果你觉得有必要打电话,那么我会说你在其他地方做过一些坏事或错事。

如果我们谈论使用Java 1.4或之前,有时我发现它确实需要帮助。 没有任何例子可以提供(对不起),但我确实记得当它决定最终开始时需要提示它以避免可怕的延迟。在6上使用相同的代码,问题消失了并且调用它几乎没有差别。

当然,当您调用System.gc()您实际上正在向VM建议现在可能是运行垃圾收集器的好时机。 这并不意味着它实际上会,它只是一个完全有效的VM实现可能完全忽略的建议。 实际上甚至还有一个DisableExplicitGC选项,这意味着这些调用肯定不会生效(生产环境中的大量代码都是使用此选项运行的。)

所以是的,它仍然在代码中使用 – 但绝大多数时候它根本不是好的做法。

显式anti-pattern to use System.gc()是一种anti-pattern to use System.gc() ,尽管我们使用它来建议JVM扫描垃圾,但是它是否由JVM决定,它是否会在System.gc()时进一步强加一些标准System.gc()发生。 如果遵循标准则行动起来; 否则没有。

 It is said that we cannot force the garbage collection process in java. 

这是一个非常流行的信念,这是完全错误的。

有几个应用程序定期执行此操作,有些应用程序甚至还有可以单击的shiny按钮,它们确实可以执行GC。 换句话说:他们没有“提示”GC他们希望GC触发,但他们确实强制GC。

所以这种信念既受欢迎也有错误。 不太受欢迎的是关于你如何实际触发这样一个GC的知识,正如我在这里提出的+6倍投票问题的独特(且非常模糊)答案所示:

Java:你如何使用JVMTI的ForceGargabeCollection强制GC?