The Second Most Important GC Tuning Knob
By jonthecollector on Sep 11, 2006
NewRatio is a flag that specifies the amount of the total heap that will be partitioned into the young generation. It's the tenured-generation-size / young-generation-size. A NewRatio value of 2 means that the tenured generation size is 2/3 of the total heap and the young generation size is 1/3. There are other ways of specifying that split. MaxNewSize will specify the maximum size of the young generation. The flag -XmnNNN is equivalent to -XX:NewSize=NNN and -XX:MaxNewSize=NNN. NewSize is the initial size of the young generation.
Say you've chosen the right size for your overall heap. But does the value of NewRatio split the space between the young generation and the tenured generation optimally. If your application has a large proportion of long lived data, the value of NewRatio may not put enough of the space into the tenured generation. I recently was looking at the performance of an application where too many major collections where being done. The problem was that the long lived data overflowed the tenured generation. When a collection was needed the tenured generation was basically full of live data. Much of the young generation was also filled with long lived data. The result was that a minor collection could not be done successfully (there wasn't enough room in the tenured generation for the anticipated promotions out of the young generation) so a major collection was done. The major collection worked fine, but the results again was that the tenured generation was full of long lived data and there was long lived data in the young generation. There was also free space in the young generation for more allocations, but the next collection was again destined to be a major collection. By decreasing the space in the young generation and putting that space into the tenured generation (a value of NewRatio larger than the default value was chosen), there was enough room in the tenured generation to hold all the long lived data and also space to support minor collections. This particular application used lots of short lived objects so after the fix mostly minor collections were done.
Why not just make NewRatio conservatively large to avoid this situation? You want your young generation to be large enough so that objects have a chance to die between collections. Applications with many threads may be allocating at a high rate so a large young generation might be appropriate.
The point here is that if you choose your overall heap size carefully, also think about the size of the young generation. This is particularly true if the maximum size of your heap is constrained for some reason (e.g., by a limited amount of physical memory).
Something to add here is that the default value of NewRatio is platform dependent and runtime compiler (JIT) dependent. Below are the values as we get ready for the JDK6 release.
-server on amd64 2 -server on ia32 8 -server on sparc 2 -client on ia32 12 -client on sparc 8These reflect the expectation that the server compiler will be used on applications with more threads and so have higher allocation rates.
And, finally, if you're about to ask why there are different ways to set the size of the young generations:
NewRatio gives you a way to scale the young generation size with the total heap size.
NewSize and MaxNewSize give you precise control.
-Xmn is a convenience