Without getting into too much detail on the generational memory management model in Java, the basic principal is that new objects are created in the young generation and are garbage collected when they are no longer used. If an object is created, and a reference is maintained, that object is eventually moved to the old generation.

Note:

If you intend to use the garbage first (G1) collector, let the JVM handles this aspect of the heap because specific settings can affect the performance of the G1 collector adversely.

Skip to Fine-tuning JVM options for instructions on fine-tuning memory and garbage collection settings.

The processing model of PingFederate is mostly geared towards short-lived transactions (single sign-on and token processing) and not long held, interactive, user sessions. As such, most of the objects that are created are relatively short-lived. It does not make sense to promote short-lived objects to the old generation because they are probably not going to be needed for long anyway. The problem is that when the young generation fills up, space must be made for new objects. So objects that are in the young generation and still in use must be moved to the old generation, which has a cost. Moreover, those objects will eventually become garbage and need to be collected from the old generation.

The old generation is typically more expensive to clean up than the young generation because the old generation is cleaned only during a full garbage collection (meaning that the JVM has almost reached the value of the maximum heap variable (-Xmx) and the entire heap must be cleaned). However, the young generation is garbage collected more frequently and with multiple threads by default (on systems with multiple cores), so the pauses for collections are shorter.

By default, the JVM tends to size the generations biased to the old generation, giving it most of the total space of the heap. This means more frequently moving objects from the young generation into the old generation to make space for new objects, and more frequent full collections as the old generation fills up. By configuring the JVM to provide more memory to the young generation, the frequency of the more costly full collections is reduced. You can either specify fixed values for the size of the young generation or modify the ratio of young generation to old generation.

To specify a fixed value for the young generation, use the -XX:NewSize= and -XX:MaxNewSize= arguments. These arguments are to the young generation what the minimum heap variable (-Xms) and the maximum heap variable (-Xmx) are to the entire heap: the -XX:NewSize= and -XX:MaxNewSize= arguments define the initial (or minimum) and the maximum sizes of the young generation. The same reasoning that applies to the minimum and maximum heap variables are also applicable when adjusting these values.

To specify a ratio between the old and new generation size, use the -XX:NewRatio= argument. For example, setting -XX:NewRatio=3 means that the ratio between the young and old generation is 1:3. Put another way, the size of the young generation is one fourth of the total heap size.

In a mostly short-lived object environment, it is recommended that 50-60% of the heap be given to the young generation; for example:
Young generation bias condition JVM options
To fix a heap size of 2 GB with 50% the young generation bias using the NewSize argument
-Xms2048m
-Xmx-2048m
-XX:NewSize=1024m
-XX:MaxNewSize=1024m
To fix a heap size of 2 GB with 50% the young generation bias using the NewRatio argument
-Xms2048m
-Xmx-2048m
-XX:NewRatio=1