2. The amount of memory reclaimed by a full GC is less than the value specified by the
-XX:GCHeapFreeLimit= N flag. The default value for this is 2, meaning that if less
than 2% of the heap is freed during the full GC, this condition is met.
3. The above two conditions have held true for five consecutive full GC cycles (that
value is not tunable).
4. The value of the -XX:+UseGCOverheadLimit flag is true (which it is by default).
Note that all four of these conditions must be met. It is common to see more than five con-
secutive full GCs occur in an application that does not throw an out of memory error. That is
because even if the application is spending 98% of its time performing full GCs, it may be
freeing more than 2% of the heap during each GC. Consider increasing the value of
GCHeapFreeLimit in that case.
Note that as a last-ditch effort to free memory, if the first two conditions hold for four con-
secutive full GC cycles, then all soft references in the JVM will be freed before the fifth full
GC cycle. That often prevents the error, since that fifth cycle will likely free more than 2% of
the heap (assuming that the application uses soft references).
1. Out of memory errors are thrown for a variety of reasons; do not assume that the
heap space is the problem.
2. For both permgen and the regular heap, out of memory errors most frequently oc-
cur because of memory leaks; heap analysis tools can help to find the root cause
of the leak.
Using Less Memory
The first approach to using memory more efficiently in Java is to use less heap memory. That
statement should be unsurprising: using less memory means the heap will fill up less often,
requiring fewer GC cycles. The effect can multiply: fewer collections of the young genera-
tion means the tenuring age of an object is increased less often—meaning that the object is
less likely to be promoted into the old generation. Hence, the number of full GC cycles (or