The first thing I learned about CMS is more memory than other collectors, which is 25-50% a good starting point. This will help you avoid fragmentation, as the CMS does not make any consolidations, such as stopping global collectors. Secondly, do what helps the garbage collector; Integer.valueOf instead of the new Integer, get rid of anonymous classes, make sure that inner classes do not have access to inaccessible things (private in the outer class). The less trash, the better. FindBugs, as well as ignoring warnings, will help a lot.
Regarding customization, I found that you need to try a few things:
-XX: + UseConcMarkSweepGC
Tells the JVM to use CMS in the extended gen.
Correct the size of your heap: -Xmx2048m -Xms2048m This prevents things such as expanding and shrinking the heap from executing the GC.
-XX: + UseParNewGC
use a parallel rather than a serial meeting in the younger generation. This will speed up your small collections, especially if you have a very large young gene set up. A large young generation is usually good, but not more than half the old size.
-XX: ParallelCMSThreads = X
set the number of threads that the CMS will use when they do what can be done in parallel.
-XX: + Note CMSParallelRemarkEnabled is serial by default, this can speed up the process.
-XX: + CMSIncrementalMode allows applications to run more by passing GC between phases
-XX: + CMSIncrementalPacing allows the JVM to display the change in how often it collects over time
-XX: CMSIncrementalDutyCycleMin = X Minimum amount of time spent executing the GC
-XX: CMSIncrementalDutyCycle = X Start by executing the GC this% of the time
-XX: CMSIncrementalSafetyFactor = X
I found that you can usually get a low pause if you tune it so that it basically gathers. Since most of the work is done in parallel, you get mostly regular predictable pauses.
-XX: CMSFullGCsBeforeCompaction = 1
It is very important. He tells the CMS collector to always fill the collection before she starts a new one. Without this, you may encounter a situation where it removes a bunch of work and starts again.
-XX: + CMSClassUnloadingEnabled
By default, CMS will allow your Permigent to grow until he kills your application in a few weeks. It stops it. Your PermGen will only grow if you use Reflection or abuse String.intern or do something bad with the class loader or a few other things.
The ratio of survivors and ownership of them can also be reproduced, depending on whether you have long or short-lived objects and how much the object copies between the survivors with whom you can live. If you know that all your objects will adhere to, you can set the size of the survivors to zero, and everything that is saved in one collection of young people will be immediately transferred.