简体   繁体   English

显式调用System.gc()?

[英]Calling System.gc( ) explicitly?

It is said that we cannot force the garbage collection process in java. 据说我们不能强制java中的garbage collection过程。
It's after all, a daemon thread. 毕竟,它是一个守护程序线程。

But still sometimes, why we call the System.gc( ); 但有时候,为什么我们称之为System.gc( ); function explicitly ? 功能明确?
Is it worth calling it ? 值得一试吗? Any Pro's and Con's ? 任何Pro和Con的?
If not useful in many situations, why this method is not deprecated from Java ? 如果在许多情况下没用,为什么不从Java中弃用此方法?

PS : Explanation with an example will be useful PS:用例子说明会很有用

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. 在我看来,最好的方法是考虑System.gc()方法,作为垃圾收集应该运行的VM的“提示”。 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). 系统正在发展等等,还有一些实例,开发人员可能实际上知道更好,它的用例可能非常类似于为什么一些代码仍然用汇编编写(大多数时候,编译器更好) ,但在少数情况下 - 或者与少数开发人员 - 人类实际上可以编写更有效的代码)。

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更多的内存利用率信息(或者至少在它实现之前),并且由于回收的内存量很大,因此建议它运行是有意义的。

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:-DisableExplicitGC command 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(); 好吧,可能有一个:一些应用程序喜欢显示堆上可用的可用内存量,并且在刷新显示之前,调用System.gc();可能是适度的System.gc(); before it. 在它之前。

Q: why we call the System.gc( ); 问:为什么我们称之为System.gc(); function explicitly ? 功能明确?

A: Because somebody wrote bad code. 答:因为有人写错了代码。

I think most people would agree that you shouldn't call 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是一个坏习惯?

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. 大多数时候,让它以自己的方式工作更好。

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. 不打算回答这个问题,明确地调用垃圾收集器是一个糟糕的坏习惯,但是java中的一些代码确实依赖于最终化......并试图强制执行它。 Calling it is useful in some profiling scenarios as well. 调用它在一些分析场景中也很有用。 No standard JVM ignores System.gc(). 没有标准JVM忽略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. 但是,b / c在内存中垃圾收集器管理对外部资源的java引用,可能需要它。

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

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. 它是一种anti-pattern to use System.gc()显式地anti-pattern to use System.gc() ,虽然我们使用它来建议JVM扫描垃圾,但它是由JVM决定它是否会,它进一步强加了一些它在System.gc()时考虑的标准System.gc()发生。 If criteria follows then it acts; 如果遵循标准则行动起来; otherwise not. 否则没有。

What version of Java are we talking about here? 我们在这里谈论的是什么版本的Java? In 6, I'd never call it explicitly. 在6,我从来没有明确地称它。 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. 作为一般的经验法则,垃圾收集器足以知道何时最好地清理资源,并且它具有足够的可配置VM选项。 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. 如果你觉得有必要打电话,那么我会说你在其他地方做过一些坏事或错事。

If we're talking about working with Java 1.4 or before though, sometimes I find it does need a helping hand. 如果我们谈论使用Java 1.4或之前,有时我发现它确实需要帮助。 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. 没有例子可以提供(抱歉),但我确实记得当它决定最终开始时,需要提示它以避免可怕的延迟。在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. 当然,当您调用System.gc()您实际上正在向VM建议现在可能是运行垃圾收集器的好时机。 It doesn't mean it actually will, it's merely a suggestion that a perfectly valid VM implementation might entirely ignore. 它并不意味着它实际上会,它只是一个建议,一个完全有效的VM实现可能完全忽略。 In fact there's even a DisableExplicitGC option that mean these calls definitely won't take affect (and lots of code in production environments is run with this option.) 实际上甚至还有一个DisableExplicitGC选项,这意味着这些调用肯定不会生效(生产环境中的大量代码都是使用此选项运行的。)

So yes, it is still used in code - but the vast majority of the time it's not good practice at all. 所以是的,它仍然在代码中使用 - 但绝大多数时候它根本不是好的做法。

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 really perform a GC. 有几个应用程序会定期执行此操作,有些应用程序甚至可以单击闪亮的按钮来实际执行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。

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?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM