How to Force Garbage Collection in Java

Can I Force Garbage Collection in Java?

Nope, System.gc() is as close as you can get. Java isn't C or C++, the JVM manages memory for you, so you don't have that kind of fine grained control. If you set objects you're no longer using to null, or loose all references, they will get cleaned up. And the GC is pretty smart, so it should take good care of you.

That said, if you are on a unix box, and force a thread dump (kill -3), it'll pretty much force garbage collection.

How do you Force Garbage Collection from the Shell?

You can do this via the free jmxterm program.

Fire it up like so:

java -jar jmxterm-1.0-alpha-4-uber.jar

From there, you can connect to a host and trigger GC:

$>open host:jmxport
#Connection to host:jmxport is opened
$>bean java.lang:type=Memory
#bean is set to java.lang:type=Memory
$>run gc
#calling operation gc of mbean java.lang:type=Memory
#operation returns:
null
$>quit
#bye

Look at the docs on the jmxterm web site for information about embedding this in bash/perl/ruby/other scripts. I've used popen2 in Python or open3 in Perl to do this.

UPDATE: here's a one-liner using jmxterm:

echo run -b java.lang:type=Memory gc | java -jar jmxterm-1.0-alpha-4-uber.jar -n -l host:port

Java Force Garbage collection without using JVMTI?

I think that the answer is No.

But I also think that you shouldn't need to do this anyway.

The way to request the garbage collector to run is to call System.gc(). But as the javadoc explains, this can be ignored.

The normal reason that System.gc() is ignored is that the JVM has been launched with the option -XX:+DisableExplicitGC. This is NOT the default. It only happens if the person or script or whatever launching the JVM wants this behavior.

So you are really asking for a way for an application override the user or administrator's explicit instructions to ignore System.gc() calls. You should not be doing that. It is not the application or the application writer's prerogative to override the user's wishes.

If your Java application really needs to run the GC explicitly, include in the installation instructions that it should NOT be run with the -XX:+DisableExplicitGC option. Then System.gc() should work.


So why did they provide a way to disable gc() calls?

Basically because explicitly running the gc() is bad practice (see Why is it bad practice to call System.gc()?) and (nearly always1) unnecessary in a properly written application2. If you application relies on the GC running at specific times to function, then you have made a mistake in the application design.

1 - A couple of exceptions are test cases for code that uses Reference types and similar, and interactive games where you want to (say) clean up between levels to avoid a GC pause during normal play.

2 - It is not uncommon for a Java programmer to start out as a C or C++ programmer. It can be difficult for such people to realize that they don't need to take a hand in Java memory management. The JVM (nearly always) has better understanding of when to run the GC. People also come across Object.finalize and dream up "interesting" ways to use it ... without realizing that it is an expensive and (ultimately) unreliable mechanism.

Forcing Java virtual machine to run garbage collector

No, You cant force garbage collection.

Even using

System.gc();  

You can just make a request for garbage collection but it depends on JVM to do it or not.

Also Garbage collector are smart enough to collect unused memory when required so instead of forcing garbage collection you should check if you are handling objects in a wrong way.

If you are handling objects in a wrong way (like keeping reference to unnecessary objects) there is hardly anything JVM can do to free the memory.

From Doc

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.

Open Bug regarding System.gc() documentation

The documentation for System.gc() is extremely misleading and fails to
make reference to the recommended practise of never calling
System.gc().

The choice of language leaves it unclear what the behaviour would be
when System.gc() is called and what external factors will influence
the behaviour.

Few useful link to visit when you think you should force JVM to free up some memory

1. How does garbage collection work

2. When does System.gc() do anything

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

All says

1. You dont have control over GC in Java even System.gc() dont guarantee it.

2. Also its bad practise as forcing it may have adverse effect on performance.

3. Revisit your design and let JVM do his work :)

Force garbage collection manually

No, there is no way to manually force Java GC with 100% probability.

Moreover you can have a GC which does no actual work e.g. JEP 318 Epsilon, A No-Op Garbage Collector.

Why JVM is designed in a way that it does not allow force Garbage Collection?

Forcing garbage collection is inefficient, and unnecessary in most cases1 ... if you have written your program correctly.

Reference:

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

It turns out that if you control the launching of the JVM that will run your application (or applet or servlet or whatever) then you can ensure that calling System.gc() will run the GC. Or at least, that is the case with Sun / Oracle JVMs ... where the behaviour is controlled via a -XX option on the java command.

The point that the javadoc is making is that this is platform dependent, and a portable application can't rely on it.


As to your question:

WHY JVM is designed in a way that it doesn't support Force Garbage Collection?

So that the JVM can be protected against the performance impact of badly written code; e.g. in applets, plugins, 3rd-party libraries, etc.

(And I imagine, in part because the original Sun engineers got a bit fed up with people complaining that "Java is slow" when the real problem was unnecessary calls to System.gc() ...)


1 - But not always. For example, calling System.gc() at a convenient time can be a way to avoid a GC-related pause at an inconvenient time. However, if your code only works if you run the GC at certain points, then you are doing something wrong.



Related Topics



Leave a reply



Submit