[concurrency-interest] Revisit of the early GC issue that Hans brought up

Gregg Wonderly gregg at cytetech.com
Tue Mar 24 10:52:00 EDT 2009


I have a JDBC factory/connection caching class which I've used for more than a 
decade.  Its basic usage is something like

DatabaseManager mgr = SQLFactory.getConnection( url, driver, user, passwd );
try {
	ResultSet rs = mgr.executeQuery(...);
	while( rs.next() ) {
	}
	rs = mgr.executeQuery( ... );
	if( rs.next() == false ) {
		mgr.executeUpdate(...);
	}
} finally {
	// close Statement, ResultSet etc., but cache the Connection.
	mgr.release();
}

It tracks all ResultSet and Statement usage internally and closes things before 
creating new ones to eliminate all the try{} finally{ closeSomething() } nesting
that is typically necessary.

Recently, while using this in another project, a new developer on my team had 
some complex code where a long lived bug was causing some stale Connection 
objects to not be closed correctly.  I decided to introduce the use of my 
ReferenceTracker class to manage the closing of those "lost" Connection instances.

What I found, was that this mostly worked, except that the behavior which Hans 
detailed about premature GC became visible, and connections where getting 
"freed" before the mgr.release() call had been made, and the GC path into the 
release of those objects was causing Connections to be aborted/closed before the 
mgr.release() call occured.

So, I had to take that back out, and I'm trying to decide if there is a way to 
still make this work without massive changes in code already using this class to 
add synchronized( mgr ){} everywhere.

Gregg Wonderly


More information about the Concurrency-interest mailing list