GC and behave quite well. Sometimes I even work on applications in environments where
memory is severely constrained; those applications end up spending 10% to 15% of their
time in GC. GC has a substantial impact on the performance of those applications, but the
overall performance goals are still met.
So the best setting will vary depending on the application goals. In the absence of other
goals, I start with a time ratio of 19 (5% of time in GC).
Table 6-1 shows the effects of this dynamic tuning for an application that needs a small heap
and does little GC (it is the stock servlet running in GlassFish where no session state is
saved, and there are very few long-lived objects).
Table 6-1. Effect of dynamic GC tuning
End heap size Percent time in GC OPS
MaxGCPauseMillis=50ms 560 MB
By default, the heap will have a 64 MB minimum size and a 2 GB maximum size (since the
machine has 8 GB of physical memory). In that case, the GCTimeRatio works just as expec-
ted: the heap dynamically resized to 649 MB, at which point the application was spending
about 1% of total time in GC.
Setting the MaxGCPauseMillis flag in this case starts to reduce the size of the heap in order
to meet that pause time goal. Because there is so little work for the garbage collector to per-
form in this example, it succeeds and can still spend only 1% of total time in GC, while
maintaining the same throughput of 9.2 OPS.
Finally, notice that more isn't always better—a full 2 GB heap does mean that the application
can spend less time in GC, but GC isn't the dominant performance factor here, so the
throughput doesn't increase. As usual, spending time optimizing the wrong area of the ap-
plication has not helped.
If the same application is changed so that the previous 50 requests for each user are saved in
the session state, the garbage collector has to work harder. Table 6-2 shows the trade-offs in