Young vs. Old Generation GC

Abstract:A few weeks ago, I tried to demonstrate the effects of old vs. new generation GC. The results surprised me and reemphasized how important GC is to your overall program performance.

Welcome to the 115th edition of The Java(tm) Specialists' Newsletter. I am on the island
of Crete again, this time with the whole family. We are
enjoying the beauty and hospitality. Swimming was possible
almost every day, even though it is already October! One of
my dreams is to run Java courses here, far away from the
distractions of the office. Just imagine: Java exercises
combined with snorkeling and swimming in the sea. We are
planning some amazing specials for our subscribers so that
you can also experience this wonderful island.

My short trips to France and USA were very enjoyable. In
France we did a design workshop followed by some Design
Patterns. In the USA, I spoke at the Java In Action
conference. Much to my delight, the room was packed to
full capacity. Thanks all for attending! And thanks to the
organisers for putting on a great conference! This was the
very first time I got to go to the USA, and it certainly was
quite an experience!

We've travelled enough (for now) and are looking forward to
going home to South Africa soon.

Young vs. Old Generation GC

It is common knowledge that it is more efficient to GC young
than old generations. You should therefore
avoid middle-aged objects.
This is also a reason why object pooling is discouraged. You
might end up with more objects in old space, which will slow
down your GC. How much it slows down is interesting to
watch.

Let's have a look at some simple classes derived from a CreateTest class.
ObjectCreationTest1 contains
an infinite loop that simply creates objects. A question here: what
percentage of CPU time do you estimate is spent collecting garbage?
40%, 50%, 60%, 70%? ObjectCreationTest2 keeps an array of the last million
created objects. Does the JVM need more CPU to collect garbage?

In my run, ObjectCreationTest1 created 8,762,510,385
objects and ObjectCreationTest2 only managed to create
389,105,915 objects.

A nice free tool that I learned about at Java In Action is
JTune by HP which we can use to see what happened in the GC logs.
I do not have a direct link to the tool, but you should be able
to find one on the Java Performance
Tuning.com website.

Using HP JTune, we should see that with ObjectCreationTest1, we
get statistics such as:

Duration of the measurement: 123s

Total bytes allocated: 66,980 MB

Number of GC events: 133,961

Time spent in GC: 11s

Percentage of time in GC: 9%

It must be said that the 134 thousand GCs all occurred in the
young generation. Since the object references were immediately
cleared, the objects were never moved into the old generation.

Again using HP JTune, we should see that with ObjectCreationTest2, we
get statistics such as:

Duration of the measurement: 123s

Total bytes allocated: 2,975 MB

Number of GC events: 1,455

Time spent in GC: 96s

Percentage of time in GC: 78%

Here the created objects live long enough to be pushed into the
old generation or the young space could not accommodate new
objects. The system only did 1165 young gen collections, and 290
old gen collections.

Object pools tend to let objects survive longer, thereby pushing
them into the old generation space. This may be bad for
performance due to the additional overhead of old gen GC, as seen
here.

During Kirk Pepperdine's talk on performance, the question arose as
to what percentage of GC activity was acceptable in a real system.
In Kirk's experience, you should aim for 5%, but maximum 10%.
The first example effectively does
while(true) { new Object(); }
but it only spends 9% of its CPU doing garbage collection. We should
be careful to not be too generous in allocating CPU cycles to the GC.

Sanity Check

Here is another test that sits in the infinite loop and is counting
how quickly the looping works, which is basically what would happen
when no objects are created. The loop executed 24,362,038,313
times in two minutes.

Oracle and Java are registered trademarks of Oracle and/or its
affiliates. Other names may be trademarks of their respective
owners. JavaSpecialists.eu is not connected to Oracle, Inc.
and is not sponsored by Oracle, Inc.