显式调用System.gc()?

时间:2011-01-24 17:24:46

标签: java garbage-collection daemon

据说我们无法在java中强制执行 garbage collection 进程。
毕竟,它是一个守护程序线程。

但有时候,为什么我们明确地调用System.gc( );函数? 值得一试吗?任何Pro和Con的?
如果在许多情况下没用,那么为什么不推荐使用Java?

PS:用例子说明是有用的

8 个答案:

答案 0 :(得分:9)

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

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

答案 1 :(得分:8)

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

  

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

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

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

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

答案 2 :(得分:7)

  

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

     

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

我认为大多数人会同意不应明确地致电System.gc()

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

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

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

答案 3 :(得分:3)

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

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

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

答案 4 :(得分:2)

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

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

答案 5 :(得分:0)

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

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

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

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

答案 6 :(得分:0)

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

答案 7 :(得分:-1)

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?

相关问题