Why Is It Bad Practice to Call System.Gc()

Why is it bad practice to call System.gc()?

The reason everyone always says to avoid System.gc() is that it is a pretty good indicator of fundamentally broken code. Any code that depends on it for correctness is certainly broken; any that rely on it for performance are most likely broken.

You don't know what sort of garbage collector you are running under. There are certainly some that do not "stop the world" as you assert, but some JVMs aren't that smart or for various reasons (perhaps they are on a phone?) don't do it. You don't know what it's going to do.

Also, it's not guaranteed to do anything. The JVM may just entirely ignore your request.

The combination of "you don't know what it will do," "you don't know if it will even help," and "you shouldn't need to call it anyway" are why people are so forceful in saying that generally you shouldn't call it. I think it's a case of "if you need to ask whether you should be using this, you shouldn't"


EDIT to address a few concerns from the other thread:

After reading the thread you linked, there's a few more things I'd like to point out.
First, someone suggested that calling gc() may return memory to the system. That's certainly not necessarily true - the Java heap itself grows independently of Java allocations.

As in, the JVM will hold memory (many tens of megabytes) and grow the heap as necessary. It doesn't necessarily return that memory to the system even when you free Java objects; it is perfectly free to hold on to the allocated memory to use for future Java allocations.

To show that it's possible that System.gc() does nothing, view
JDK bug 6668279
and in particular that there's a -XX:DisableExplicitGC VM option:

By default calls to System.gc() are enabled (-XX:-DisableExplicitGC). Use -XX:+DisableExplicitGC to disable calls to System.gc(). Note that the JVM still performs garbage collection when necessary.

Good practice to call System.gc()

It's fine to call System.gc(). Do use a memory analysis tool to check that it's helping in your case.

The spec can't guarantee any results since the vm might've just done a GC.

Calling System.gc( ) explicitly?

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

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.

Can we call the Garbage Collector explicitly?

You can call Garbage collector using:

System.gc();

But this does not mean that it'll be executed immediately. The JVM decides when to execute it. In general if the JVM is about to throw an OutOfMemoryError, calling System.gc() won't prevent it. Better investigate why you're leaking so much memory and clean it up along the way.

JavaDoc:

Calling the gc 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. When control returns
from the method call, the Java Virtual Machine has made a best effort
to reclaim space from all discarded objects

Why is it bad practice to call System.gc()?

The reason everyone always says to avoid System.gc() is that it is a pretty good indicator of fundamentally broken code. Any code that depends on it for correctness is certainly broken; any that rely on it for performance are most likely broken.

You don't know what sort of garbage collector you are running under. There are certainly some that do not "stop the world" as you assert, but some JVMs aren't that smart or for various reasons (perhaps they are on a phone?) don't do it. You don't know what it's going to do.

Also, it's not guaranteed to do anything. The JVM may just entirely ignore your request.

The combination of "you don't know what it will do," "you don't know if it will even help," and "you shouldn't need to call it anyway" are why people are so forceful in saying that generally you shouldn't call it. I think it's a case of "if you need to ask whether you should be using this, you shouldn't"


EDIT to address a few concerns from the other thread:

After reading the thread you linked, there's a few more things I'd like to point out.
First, someone suggested that calling gc() may return memory to the system. That's certainly not necessarily true - the Java heap itself grows independently of Java allocations.

As in, the JVM will hold memory (many tens of megabytes) and grow the heap as necessary. It doesn't necessarily return that memory to the system even when you free Java objects; it is perfectly free to hold on to the allocated memory to use for future Java allocations.

To show that it's possible that System.gc() does nothing, view
JDK bug 6668279
and in particular that there's a -XX:DisableExplicitGC VM option:

By default calls to System.gc() are enabled (-XX:-DisableExplicitGC). Use -XX:+DisableExplicitGC to disable calls to System.gc(). Note that the JVM still performs garbage collection when necessary.



Related Topics



Leave a reply



Submit