java 显式调用 System.gc()?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4784987/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 08:01:21  来源:igfitidea点击:

Calling System.gc( ) explicitly?

javagarbage-collectiondaemon

提问by sgokhales

It is said that we cannot force the garbage collectionprocess in java.
It's after all, a daemon thread.

据说garbage collection在java中不能强制进程。
毕竟,它是一个守护线程。

But still sometimes, why we call the System.gc( );function explicitly ?
Is it worth calling it ? Any Pro's and Con's ?
If not useful in many situations, why this method is not deprecated from Java ?

但有时,为什么我们System.gc( );显式调用函数?
值得称它吗?任何优点和缺点?
如果在许多情况下没有用,为什么 Java 不推荐使用此方法?

PS : Explanation with an example will be useful

PS:举例说明会很有用

采纳答案by Chris Thompson

The best way, in my opinion, to think of the System.gc()method is as a "hint" to the VM that garbage collection should run. That said, much like a large percentage of "optimizations" people think they are performing, it's usually best to just let the system take care of things on its own. Systems are evolving etc, etc, etc. There are still some instances where the developer may actually know better and the use case for it is probably very similar to why some code is still written in assembly (most of the time, the compiler is better, but in a few instances -- or with a few developers -- humans can actually write more efficient code).

在我看来,认为该System.gc()方法的最佳方式是向 VM 发出垃圾收集应该运行的“提示”。也就是说,就像人们认为他们正在执行的大部分“优化”一样,通常最好让系统自行处理事情。系统在不断发展等等,等等。仍然有一些实例,开发人员实际上可能更了解它,它的用例可能与为什么某些代码仍然用汇编编写的原因非常相似(大多数情况下,编译器更好,但在少数情况下——或者在少数开发人员的情况下——人类实际上可以编写更高效的代码)。

One example I've seen used in the past to justify its existence is in the event that a large number of objects were allocated and you as the developer know the instant they are no longer going to be used. In that case, you may have more information about the memory utilization than the GC does (or at least, before it realizes it) and, since the amount of memory reclaimed will be significant, it makes sense to suggest that it runs.

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

回答by biziclop

You answered half of your question: is it worth it? No, because you can't force it.

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

Runs the garbage collector. Calling this method suggests that the Java virtual machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse.

运行垃圾收集器。调用此方法表明 Java 虚拟机将努力回收未使用的对象,以使它们当前占用的内存可用于快速重用。

This is almost EULA-English for "you can try but we both know the outcome". :)

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

Furthermore, application servers can (and often will) disable it using the -XX:-DisableExplicitGCcommand line option.

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

So what's the point then? Well, there could be one: some applications like to display the amount of free memory available on the heap, and before you refresh your display, it could be moderately useful to call System.gc();before it.

那么有什么意义呢?嗯,可能有一个:一些应用程序喜欢显示堆上可用的可用内存量,在你刷新你的显示System.gc();之前,在它之前调用它可能会比较有用。

回答by Justin Niessner

Q: why we call the System.gc( ); function explicitly ?

A: Because somebody wrote bad code.

Q:为什么我们调用System.gc();明确地发挥作用?

A:因为有人写了不好的代码。

I think most people would agree that you shouldn'tcall System.gc()explicitly.

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

Let the system manage memory as it's supposed to. Any code relying on that for performance is most likely broken. Also, keep in mind that the JVM can entirely ignore your request.

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

If you want more information, I'd suggest reading the answers to:

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

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

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

回答by maaartinus

There are some cases when calling System.gc() is useful:

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

  • You're going to run some benchmark, so you need to start in a well-defined state.
  • You're expecting some heavy load and want to get prepared as good as possible.
  • You have multiple servers and want to avoid pauses by scheduling GC on them periodically like here.
  • 您将运行一些基准测试,因此您需要以明确定义的状态开始。
  • 您预计会承受一些沉重的负担,并希望尽可能做好准备。
  • 您有多个服务器,并希望通过像此处这样定期在它们上安排 GC 来避免暂停。

There may be more use cases, however, it's nothing you could expect to need soon. Most of the time it's better to let it do its work its way.

可能会有更多用例,但是,您很快就会需要它。大多数情况下,最好让它按照自己的方式工作。

回答by bestsss

Not intending to answer the question, calling the garbage collector explicitly is a bad, bad practice, however some code in java does rely on finalization... and attempts to enforce it. Calling it is useful in some profiling scenarios as well. No standard JVM ignores System.gc(). Sure, it can be disabled. However, b/c aside memory the garbage collector manages java references to external resources, it might be needed.

不打算回答这个问题,显式调用垃圾收集器是一种糟糕的做法,但是 Java 中的某些代码确实依赖于终结……并试图强制执行它。在某些分析场景中调用它也很有用。没有标准的 JVM 会忽略 System.gc()。当然,它可以被禁用。但是,除了内存垃圾收集器管理对外部资源的 java 引用的 b/c 之外,可能需要它。

here is some code from java.nio.Bits

这是来自 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;
    }

Sleep is necessary for the finalized to run actually (or attempted run), Cleaners usually have fast-track on the high-priority finalizer thread.

睡眠对于最终运行(或尝试运行)来说是必要的,清洁器通常在高优先级终结器线程上具有快速通道。

回答by RTA

It is an anti-pattern to use System.gc()explicitly, though we use it to suggest JVM for sweeping garbage but it is up to the JVM whether it will or not, it further imposes some criteria that it look into when System.gc()occurs. If criteria follows then it acts; otherwise not.

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

回答by Michael Berry

What version of Java are we talking about here? In 6, I'd never call it explicitly. As a general rule of thumb the garbage collector is good enough to know when best to clean up resources and it's got enough configurable VM options. I've certainly never felt the need to call it in code, and I'd say unless you were doing something really bizarre (or showing resource usage) it's best not to. If you're feeling the need to call it then I'd say you've done something bad or wrong elsewhere.

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

If we're talking about working with Java 1.4 or before though, sometimes I find it does need a helping hand. No examples to hand (sorry) but I do remember needing to throw it a hint to avoid horrible lag when it decided to eventually kick in. With the same code on 6, the problem went away and calling it made little or no difference.

如果我们谈论使用 Java 1.4 或更早版本,有时我发现它确实需要帮助。没有手头的例子(抱歉),但我确实记得当它决定最终启动时需要抛出一个提示以避免可怕的滞后。使用 6 上的相同代码,问题消失了,调用它几乎没有区别。

Of course, when you're calling System.gc()all you're actually doing is suggesting to the VM that now might be a good time to run the garbage collector. It doesn't mean it actually will, it's merely a suggestion that a perfectly valid VM implementation might entirely ignore. In fact there's even a DisableExplicitGC option that mean these calls definitely won'ttake affect (and lots of code in production environments is run with this option.)

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

So yes, it is still used in code - but the vast majority of the time it's not good practice at all.

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

回答by SyntaxT3rr0r

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

That is a very popular belief, which is totally wrong.

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

Several applications do that on a regular basis and some even have shiny buttons you can click that do reallyperform a GC. In other words: they don't "hint" the GC that they'd like the GC to trigger but they do really force a GC.

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

So that belief is both popular and wrong. What is less popular is the knowledge as to how you actually trigger such a GC, as shown by the unique (and very vague) answer to my +6 times upvoted question here:

所以这种信念既流行又错误。不太受欢迎的是关于您如何实际触发此类 GC 的知识,如对我的 +6 次投票问题的独特(且非常模糊)的回答所示:

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

Java:您如何真正使用 JVMTI 的 ForceGargabeCollection 强制执行 GC?