I'm not looking for the usual "you can only hint the GC in Java using System.gc()" answers, this is not at all what this question is about.
My questions is not subjective and is based on a reality: GC can be forced in Java for a fact. A lot of programs that we use daily do it: IntelliJ IDEA, NetBeans, VisualVM.
They all can force GC to happen.
How is it done?
I take it they're all using JVMTI and more specifically the ForceGarbageCollection (notice the "Force") but how can I try it for myself?
http://java.sun.com/javase/6/docs/platform/jvmti/jvmti.html#ForceGarbageCollection
Also note that this question is not about "why" I'd want to do this: the "why" may be "curiosity" or "we're writing a program similar to VisualVM", etc.
The question is really "how do you force a GC using JVMTI's ForceGarbageCollection"?
Does the JVM needs to be launched with any special parameters?
Is any JNI required? If so, what code exactly?
Does it only work on Sun VMs?
Any complete and compilable example would be most welcome.
NetBeans, at least, uses System.gc(): http://hg.netbeans.org/main/annotate/9779f138a9c9/openide.actions/src/org/openide/actions/GarbageCollectAction.java (this is for the little button that shows current heap and lets you start GC). If you follow that link, you'll see that they explicitly run finalizers. If you have a few gig of disk space free, and want to investigate the code yourself, it's available via Mercurial:
hg clone http://hg.netbeans.org/main/
As far as I can tell, the "System.gc() is just a hint" dogma originates in pedantic interpretation of the JLS and JVM Spec, which allow for Java implementations that don't have a garbage-collected heap. That, and an incomplete reading of the JavaDoc:
Read the second sentence: "best effort to reclaim space" is a lot stronger than "hint."
That said, there's rarely a reason to call
System.gc()
. With apologies to Knuth:As Anon has said, we have something similar in eclipse to run garbage collector explicitly.
Please have a look at Eclipse: Garbage Collector Button
This seems to work quite well. I suggest you to have a look at the code behind this "Run garbage collector" button and reuse it.
Some members say it uses System.gc() but I cannot confirm it. Eclipse experts can shed some light here.
I built a basic java agent allowing to invoke the jvmti
ForceGarbageCollection
function:This agent is invoked via JNI:
To compile the agent on MacOSX:
To launch the
Garbager
:Based on this tutorial: Own your heap: Iterate class instances with JVMTI
Yes JNI interface code is needed to use JVMTI API as it is a native API. "native" means that you can only call it directly form native (understan c or c++) code. So if you want to call this API from java you need to write JNI code to interface it.