Jon Masamitsu's Weblog

  • Java
    April 4, 2006

The Fault with Defaults

Guest Author
During early work on the low pause collector some of the applications we used for benchmarking
the collector had the characteristic that objects had very short lifetimes or relatively long lifetimes
with not much in between. All our current collectors use a copying collection for the young
generation. This copying collection will copy the younger objects back into the young generation
and copy the older objects into the tenured generation. The expectation is that more of the
younger objects will die in the young generation if they are give a little more time. A
consequence of this is that long lived objects are copied repeatedly into the young generation
before finally being promoted into the tenured generation. Depending on the mix of lifetimes of
your objects, this can be good (more objects die in the young generation) or this can be bad (extra copying into the young generation). Additionally at about the same time we were discussing the
policy of never doing the copying but rather always copying any objects that survived a young
generation collection immediately into the tenured generation. There are some collectors
that do that and there was some anecdotal evidence that it was a good strategy.
Given some example applications
where never copying back into the young generations seemed to be the right strategy and the
general discussion about what was the right policy for copying, we decided to make the default
behavior for the low pause collector to always promote
objects surviving a young generation collection into the tenured generation.

This default policy still seems reasonable for some applications but the old adage about one
size not fitting all certainly applies here. So here's what you should consider and what
you can do.

The young generation is acting like a filter to dispose of the shorter lived objects. Any objects
that get through the filter are moved to the tenured generation and are henceforth handled
by the mostly concurrent collections (which I'll just call the concurrent collections from
here on out). If the concurrent collections
are starting too often to suit your tastes, one possibility is to
filter out more of the short lived objects by doing some copying during the young generation
collections. This may slow down the growth in the number of objects in the tenured generation
and lessen the need for too frequent concurrent collections. To do this try the command line

-XX:MaxTenuringThreshold=15 -XX:SurvivorRatio=8

MaxTenuringThreshold is the number of collections that an object must survive before being promoted
into the tenured generation. When objects are copied back into the young generation during a
young generation collection, the objects are copied into an part of the young generation that is
referred to as a survivor space. SurvivorRatio set to 8 will mean that the survivor spaces are
about 10% of the size of the young generation. The survivor spaces and
SurvivorRatio are described in the 5.0 tuning guide that can be found under


The FAQ attached to the 5.0 tuning guide has an entry about experimenting with MaxTenuringThreshold.

By the way having concurrent collections starting "too often" can also be a sign that
the tenured generation is smaller than is needed for good performance. You can always try
increasing the size of the heap to reduce the frequency of the concurrent collections.
The suggestions above may be able to get you the less frequent concurrent collections
without the longer concurrent collections that typically come when the heap is increased.

The default setting to always promote objects that survive a young generation collection is
only the default for the low-pause collector. The other collectors by default will do
some copying before promoting an object to the tenured generation.

Join the discussion

Comments ( 2 )
  • Brice Beard Tuesday, April 4, 2006
    Most of the apps I worked on were best served by a relatively large new generation and tenuring thresholds of 32, but still it is annoying to have all long lived object being copied N times unnecessarily, particularly at startup. I tried to trick this behavior with the Initial tenuring threshold + a max, but really it would be really usefult to be able to mark object as long lived so the GC can move them efficiently to the old generation, and keep the good behavior of copying GC in the new gen.
  • Jon Masaumits Tuesday, April 4, 2006
    It would certainly make our lives easier if we got
    hints about the expected life times of objects,
    I'm guessing that it would be difficult for most
    users to provide that information. There is the
    concept of pre-tenuring objects (i.e., allocating
    certain objects directly into the tenured
    generation) but the usefulness of the
    idea in hotspot is very, very limited. You can
    say that you want large objects beyond a
    certain size to be considered for pre-tenuring.
    I can't recall anyone using it. Another group
    at Sun took a look at the idea of identifying
    allocation sites at which long lived objects
    were created. Later allocations from those
    sites could then be pre-tenured. Maintaining
    the information requires both time and space,
    and I think the idea needed more tuning before
    the benefits out weighed the costs.

    The throughput collector with GC ergonomics
    tries a different approach. The collector
    adjusts the
    tenuring threshold in order to move GC work
    to or from the young generation collections.
    If the GC ergonomics decides that more work
    is being done in the young generation collections
    than in the tenured generation collections,
    the tenuring threshold is lowered to more
    quickly move objects into the tenured
    generation. This a coarse adjustment when
    compared to pre-tenuring (which is at the
    object level) and certainly does not take
    the place of pre-tenuring. It does try to
    adjust the copying costs to reduce the overall
    cost of GC.

Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.