1. Avoiding concurrent mode failures is the key to achieving the best possible per-
formance with CMS.
2. The simplest way to avoid those failures (when possible) is to increase the size of
3. Otherwise, the next step is to start the concurrent background threads sooner by
adjusting the CMSInitiatingOccupancyFraction .
4. Tuning the number of background threads can also help.
Tuning CMS for Permgen
The example CMS GC log showed that a full GC occurred when permgen needed to be col-
lected (and the same thing can happen if the metaspace needs to be resized). This will happen
most frequently for developers who are continually (re)deploying applications to an applica-
tion server, or to any other such application that frequently defines (and discards) classes.
By default, the CMS threads in Java 7 do not process permgen, so if permgen fills up, CMS
executes a full GC to collect it. Alternately, the -XX:+CMSPermGenSweepingEnabled flag
can be enabled (it is false by default), so that permgen is collected just like the old genera-
tion: by a set of background thread(s) concurrently sweeping permgen. Note that the trigger
to perform this sweeping is independent of the old generation. CMS permgen collection oc-
curs when the occupancy ratio of permgen hits the value specified by -
XX:CMSInitiatingPermOccupancyFraction= N , which defaults to 80%.
Enabling permgen sweeping is only part of the story, though: to actually free the unreferen-
ced classes, the flag -XX:+CMSClassUnloadingEnabled must be set. Otherwise, the CMS
permgen sweeping will manage to free a few miscellaneous objects, but no class metadata
will be freed. Since the bulk of the data in permgen is that class metadata, this flag should al-
ways be used when CMS permgen sweeping is enabled.
In Java 8, CMS does clean unloaded classes from the metaspace by default. If for some reas-
on you wanted to disable that, unset the -XX:-CMSClassUnloadingEnabled flag (by default,
it is true ).