Calling System.gc( ) explicitly?

2019-01-07 22:18发布

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

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 ?

PS : Explanation with an example will be useful

8条回答
乱世女痞
2楼-- · 2019-01-07 22:49
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. In other words: they don't "hint" the GC that they'd like the GC to trigger but they do really force a 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:

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

查看更多
孤傲高冷的网名
3楼-- · 2019-01-07 22:59

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.

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.

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't take affect (and lots of code in production environments is run with this option.)

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

查看更多
劳资没心,怎么记你
4楼-- · 2019-01-07 23:04

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

  • 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.

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.

查看更多
劳资没心,怎么记你
5楼-- · 2019-01-07 23:04

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.

查看更多
混吃等死
6楼-- · 2019-01-07 23:11

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.

here is some code from 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.

查看更多
ら.Afraid
7楼-- · 2019-01-07 23:12

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

A: Because somebody wrote bad code.

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

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.

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

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

查看更多
登录 后发表回答