显式调用System.gc()?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了显式调用System.gc()?相关的知识,希望对你有一定的参考价值。

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

但有时候,为什么我们明确地称之为System.gc( );函数? 值得一试吗?任何Pro和Con的? 如果在许多情况下没用,为什么不从Java中弃用此方法?

PS:用例子说明会很有用

答案

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

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

另一答案

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

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

这几乎是EULA-英语,“你可以尝试,但我们都知道结果”。 :)

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

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

另一答案

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

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

我想大多数人会同意你不应该明确地打电话给System.gc()

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

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

java - why is it a bad practice to call System.gc?

另一答案

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

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

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

另一答案

不打算回答这个问题,明确地调用垃圾收集器是一个糟糕的坏习惯,但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;
    }

最终实际运行(或尝试运行)需要睡眠,清洁工通常在高优先级终结器线程上进行快速跟踪。

另一答案

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

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

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

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

另一答案

这是一个明确的anti-pattern to use System.gc(),虽然我们用它来建议JVM用于清扫垃圾,但它是由JVM决定它是否会,它进一步强加了一些标准,它会在System.gc()发生时查看。如果遵循标准则行动起来;否则没有。

另一答案
It is said that we cannot force the garbage collection process in java.

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

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

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

Java: How do you really force a GC using JVMTI's ForceGargabeCollection?

以上是关于显式调用System.gc()?的主要内容,如果未能解决你的问题,请参考以下文章

Java应用性能调优之详解System的gc垃圾回收方法

JVM之垃圾回收相关概念

Java面试题和解答

JVM--17---垃圾回收相关概念

JVM垃圾回收篇(重要概念解析)

JVM垃圾回收篇(重要概念解析)