Monday Dec 11, 2006

Nice performance improvement with Java SE 6!

Hey, check out this post:

http://forum.java.sun.com/thread.jspa?forumID=37&threadID=5114368

30% performance improvement by just switching from 5.0 to 6.0. Pretty Cool! As I said in my previous post: What are you waiting for? Go and get it. Now!

Java SE 6 is out!

After an enormous amount of work from the entire Java SE team, Java SE 6 is out. What are you waiting for? Go and get it. Now!

http://java.sun.com/javase/6/

Tuesday Nov 28, 2006

The Garbage Collector is too aggressive!!!

(back to blogging after a short hiatus...)

A customer recently complained to me that the GC is too aggressive, it can reclaim objects too early (Wow!), and the JIT compiler is broken for allowing the GC to do so (double Wow!)!

Here's the (simplified) example that the customer gave me:

class Foo {
	// cPtr is really a pointer to a C object in the C heap
	long cPtr;
	
	long getCPtr() { return cPtr; }
	void finalize() {
		freeCObject(cPtr);
	}

	native void freeCObject(long cPtr);
}

class Bar {
	native void processCObject(long cPtr);

	void doSomething() {
		Foo foo;
		...
		// foo now points to object F
		...
		long cPtr = foo.getCPtr();
		processCObject(cPtr);
	}
}
(If you're really into bug hunting please refrain from reading further and try to find the race in the code...)

OK, here's what happens: the JIT can prove that variable foo is not accessed after the assignment to variable cPtr and, therefore, the GC will not consider foo as part of the stack frame's live root set for safepoints that take place after the assignment (basically, foo is considered "dead" after the assignment). Imagine now that a GC happens while the native method processCObject() is running (note: JNI will do a safepoint check upon entering a method and will suspend the thread if a safepoint has been requested). Also imagine that foo is the last reference to object F. Given that foo will not be considered as part of the stack frame's live root set (remember, it is considered "dead"), the GC can decide that F is actually unreachable and queue it up for finalization. At the end of the GC, the application threads, as well as the finalization thread, will be restarted and will race for accessing the C object; the application thread will try to process it, while the finalization thread will try to free it.

Ouch.

First, how can this happen? Well, as far as the JIT is concerned, cPtr is just another long and is treated as such. So, the JIT has no way of knowing that cPtr is actually a C pointer and the object it points to is associated with foo. Hence, it will not consider foo to be live as long as cPtr is live (the JIT just does not do that for longs!).

So, what can we do to fix this bug? Well, we just have to ensure that the GC considers foo live during the duration of the processCObject() method. There are a couple of ways of doing this:

  • passing foo as an additional parameter to processCObject(), or
  • making processCObject() a non-static method on the Foo class
In both cases, JNI will create a handle for F (in the first case, because it is a parameter; in the second case because it is the target object of the method) which will ensure that F is found to be live by the GC while the JNI method is running, whether the JIT decides foo is live or not.

Another recommendation that makes it easier to avoid such problems, courtesy of Ross Knippel from our compiler group, is to avoid manipulating C-pointer-containing long fields from Java, but only manipulate them from within native methods. This way, there will always be a JNI handle pointing to the Java object that contains the C pointer which will ensure that the object will not be collected while the corresponding C object is accessed. In the above example, you will only pass foo to the processCObject() native method, which will first retrieve cPtr and then go ahead and process the corresponding C object.

This was a fun little problem (maybe, not this much fun for the customer who hit it!). What I'd like you to at least get out of this is that using native methods in Java is really not very straightforward and little problems like this one can cause major headaches. So, please, be careful!

Monday Feb 06, 2006

Predictable GC does not mean Fast GC

I recently heard some claims from one of our competitors that drove me nuts! Said competitor claimed that they have a very fast VM, which is now even faster given that they have a predictable GC!

Exqueeze me? Baking powder?*

Whoever made these claims clearly has no understanding of how garbage collection works and what the trade-offs involved are.

To achieve predictability, you have to make sacrifices. Even by going from a fully stop-the-world to a more incremental collector, you usually double your garbage collection overhead (that's my rule of thumb at least) and increase your memory footprint.

Going from a simple incremental to a really predictable collector will cost you even more. I have read papers in which a 30%-35% garbage collection overhead is considered a good result in the context of a predictable garbage collector.

In a lot of applications that our customers care about, the garbage collection overhead is maybe 10%, even as low as 5%. Predictability will not decrease that.

Incidentally, I had seen some SPECjbb (2000 I think) results from said competitor and, by looking at the configuration they ran with, I highly doubt that they had any garbage collection activity during the timing window. So, how are they going to improve that with a predictable collector? Eh?

Let me put it another way: they will not be publishing SPECjbb2005 numbers with their predictable collector any time soon...

*If you didn't get the joke, I invite you to watch Wayne's World. Even if you got the joke, watch it anyway!

Thursday Feb 02, 2006

The Mustang Regressions Challenge!

During the past two and a half weeks I visited several customers (12 to be exact). During the visits I encouraged them to move to our latest and greatest Java release (5.0_06). Unfortunately, a lot of them have trouble moving from, say, the latest 1.4.2 to Tiger (5.0) due to API incompatibilities which will force them to retest and fiddle with their code. We are listening and we are trying to do our best to ensure smooth (or mostly smooth at least! if there's something clearly broken we will fix it!) transitions to the latest Java release. And we encourage you to try our latest Mustang releases out and identify such problems. For this we have launched The Mustang Regressions Challenge! Please report any incompatibilities between Tiger and Mustang; if you find a "biggie" you'll have a chance to win a Sun Ultra 20 workstation!

Thursday Jan 05, 2006

Finalization and Resource Retention.

Hi all and Happy New Year!

An article I wrote on how finalization can cause unpredictable memory and resource retention and how to deal with such problems has just been published by DevX. You can find it here. Comments are welcome!

That's the second article that I published on DevX. The first one was an overview of the garbage colletors in HotSpot. You can find that one here, if you're interested.

Tuesday Dec 20, 2005

New Year, New Adventures!

Hi all and welcome to my newly-created blog (which was a breeze to set up; I'm very impressed)!

I have been at SunLabs full-time for 3+ years now working mainly on garbage collection. I recently felt that I needed a change and a new challenge. So, as the last digit of the year is about to change, I am transferring to the HotSpot garbage collection team. I have been collaborating with the guys in the team for some time now, I know them pretty well, and I'm really looking forward to joining them and contributing.

I'm also really excited about working more with developers and understanding their (your?) needs to ensure that my work is topical and relevant. Lots of people claim that GC is a solved problem. Still, there's still lots of interesting and cool stuff to do and I'd better stop writing this and get back to work!

In the blog I'll try to cover latest news from the team, as well as my personal views (and rants!) on garbage collection.

And on that note, I'd like to wish you all happy holidays and a very happy new year! And keep reloading this page!