Skip to Main Content

Java HotSpot Virtual Machine

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

do System.runFinalization and System.gc need to be called many times?

843829Feb 24 2008 — edited Feb 24 2008
I have an application in which it is desirable to ensure that automatic resource reclamation (e.g. garbage collection and object finalization) does not occur in the middle of a certain operation.

I realize that this is ultimately under the control of the JVM, so there is nothing that I can do to guarantee the above. But you can at least try; I call a method named restoreJvm before the operation, and its current, rather paranoid, implementation is something like
	long memUsedPrev = Long.MAX_VALUE;
	long memUsedNow = memoryUsed();
	for (int i = 0; i < maxRestoreJvmLoops; i++) {
		System.runFinalization();	// see also: http://java.sun.com/developer/technicalArticles/javase/finalization/
		System.gc();

		//Thread.currentThread().yield();	// no longer use, since is just a hint; see: http://www.faqs.org/docs/think_java/TIJ315.htm
		TimeUnit.MILLISECONDS.sleep(pauseTime);

		if (memUsedPrev > memUsedNow) {	// the first time execute this loop are guaranteed to satisfy this, since memUsedPrev = Long.MAX_VALUE now, which guarantees that the loop will execute at least twice, as per method contract
			memUsedPrev = memUsedNow;
			memUsedNow = memoryUsed();    // the memoryUsed method is defined elsewhere, and does just what its name says
		}
		else {	// break early if get constant mem used (memUsedPrev == memUsedNow; actually, will break early if < too, but this is unlikely to happen)
			//System.out.println("achieved stable memory (memUsedPrev = " + memUsedPrev + " <= memUsedNow = " + memUsedNow + ") at i = " + i);
			break;
		}
	}
Here, I call System.runFinalization and System.gc as many times as is necessary in order for heap usage to stabilize. I got the idea for this from this old article:
http://www.javaworld.com/javaworld/javatips/jw-javatip130.html
The above article claims that many calls are necessary because "Executing a single Runtime.gc() call may not prove sufficiently aggressive for requesting garbage collection. We could, for example, request object finalizers to run as well. And since Runtime.gc() is not documented to block until collection completes, it is a good idea to wait until the perceived heap size stabilizes."

But I just reread the javadocs for
runFinalization http://java.sun.com/javase/6/docs/api/java/lang/System.html#runFinalization()
and
gc http://java.sun.com/javase/6/docs/api/java/lang/System.html#gc()
and both claim "When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects (gc)/complete all outstanding finalizations (rf)".

That "When control returns..." bit seems to contradict the article's claim that Runtime.gc does not block.

Does anyone know what the real situation is? Can I safely call System.runFinalization and System.gc just once, or do I need to use the current aggressive code above?
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Mar 23 2008
Added on Feb 24 2008
4 comments
365 views