Arch2Arch Tab BEA.com
Syndicate this blog (XML)

Control Your Youngsters - Nursery Sizing and its Problems

Bookmark Blog Post

del.icio.us del.icio.us
Digg Digg
DZone DZone
Furl Furl
Reddit Reddit

Noora Peura's Blog | March 4, 2008   6:11 AM | Comments (0)


Many Java applications allocate a lot of temporary short lived objects. Swift allocation and garbage collection of these short lived objects can improve the application throughput significantly. Thus most modern garbage collectors, including the ones in BEA JRockit, use a separate space for newly allocated objects. The name of this space varies. In BEA JRockit we call it the "nursery" or the "young space".

An ordinary garbage collection traverses all references in all objects in the heap, while a garbage collection of the nursery (young collection) only traverses references that have changed since the last garbage collection. Any "live" objects found in the nursery are promoted (moved) to the "old space". This frees up the entire nursery for swift new object allocation. Using a nursery will thus improve both garbage collection efficiency and object allocation speed.

The BEA JRockit Diagnostics Guide contains information on how to tune the nursery size, so I will not go into those details here. Instead I will talk a little about the rationales behind the dynamic nursery sizing heuristics and the problems that both BEA JRockit and anyone who attempts to tune the nursery size manually may encounter.

The Basics

Figures 1-3 illustrate a basic scenario with a nursery and an old space. Objects are allocated in the nursery, and when the nursery is full the objects that are still alive are promoted to the old space.

Let's say that each allocated object lives for exactly ten seconds, no more and no less. Thus, when the nursery becomes full the only live objects within the nursery are the ones that were allocated less than ten seconds ago. In a simple young collection (without a keep area) these are the objects that would be promoted. Ideally, the size of the nursery wouldn't matter at all. The young collections promote the same amount of objects as long as they're at least ten seconds apart. In this world, a larger nursery size would mean that each young collection frees a larger amount of memory. Also, the frequency of old collections would depend directly on the size of the old space - a smaller old space would mean more frequent old collections. Since the nursery is a part of the heap, and the old space is what is left of the heap when the nursery has been reserved, a larger nursery would allow fewer young collections before an old collection must be performed.

Figure 1: The Heap
os_nursery.jpg

Figure 2: "Before"
nursery_w_objects.jpg

Figure 3: "After"
nursery_promoted.jpg

Your goal here is to get as much memory as possible freed by young collections rather than old collections. I won't go into the details on why, but surprisingly it turns out that a nursery size of approximately half of the free memory on the heap is nearly optimal in this sense.

Promoting objects just because they haven't had a chance to die yet when the young collection starts feels a bit silly. Thus BEA JRockit uses something called a "keep area". The last bit of the nursery is designated as the "keep area", and objects within the keep area won't be promoted until the second young collection after they were created, providing that they still are alive at that point. In our optimal world where objects always live exactly ten seconds, we would tune the keep area to fit exactly these objects, and nothing would ever be promoted. In this world, the nursery size could be increased almost indefinitely, since the old space only has to have space for a few long lived objects.

Figures 4-6 illustrate a young collection using a keep area. As you can see, no objects are promoted in this example.

Figure 4: The Heap
os_ns_keeparea.jpg

Figure 5: "Before"
keeparea_w_objects.jpg

Figures 6: "After"
keeparea_after_yc.jpg

The Quirks

Now, BEA JRockit has a little quirk: large objects can be allocated directly in old space. Thus, if your application allocates a lot of large objects, the old space may become full before even one young collection has been performed. Don't worry, you can fix that too. Just set the limit for what objects to consider "large" higher, using the option -XXlargeObjectLimit. Everything smaller than the large object limit will always be allocated in the nursery.

Another aspect in nursery sizing is garbage collection pause times. If your application is sensitive to latencies you may want to decrease the nursery size to shorten the young collection pause times. The pause time isn't linearly dependent on the nursery size, but you have a fair chance to get shorter pause times by reducing the nursery size.

So, why can't BEA JRockit do this all by itself? Well, it makes a fair attempt on some of it, but unfortunately the real world has a quirk of its own: the lifetimes of the objects vary. Sometimes they vary a lot. You will notice this also when you tune the nursery size by hand. What in theory sounds optimal can turn out to be a bit off, or even quite suboptimal when the inexactness of the real world is thrown in the face of neat models and calculations.

By default, BEA JRockit optimizes garbage collection for maximum throughput. In this mode the nursery size is adjusted automatically in runtime. The nursery can even be disabled if most of the allocated objects are large. The static generational parallel garbage collector (-Xgc:genpar) uses similar heuristics to adjust the nursery size. For both these garbage collectors you can override the dynamic nursery size by setting a nursery size on the command line (-Xns:). If you're using the garbage collection mode optimizing for short pauses (-Xgcprio:pausetime) or the static generational concurrent garbage collector (-Xgc:gencon) you will most likely want to tune the nursery size manually.

Read more about nursery sizing and garbage collection in the BEA JRockit Diagnostics Guide.


Comments

Comments are listed in date ascending order (oldest first) | Post Comment



Only logged in users may post comments. Login Here.

Powered by
Movable Type 3.31