To ensure reliable server performance with Java, the Directory Server depends on Java’s Concurrent Mark and Sweep process (CMS) for background garbage collection. There are several garbage collection options, with CMS being the ideal choice for consistent system availability. The CMS collector runs as one or more background threads, for the most part, within the JVM, freeing up space in JVM Heap from an area called the Old Generation. One of the criteria used by CMS to determine when to start background garbage collection is a parameter called CMSInitiatingOccupancyFraction. This percentage value, which applies to the Old Generation, is a recommendation for the JVM to initiate CMS when data occupancy in Old Generation reaches the threshold.

To understand this CMS property, it is important to know how large the Old Generation is and how much data in the Old Generation is expected to be occupied by the database cache. Ideally, the database cache takes less than 70% of the space available in the Old Generation, and the CMSInitiatingOccupancyFraction value of 80 leaves plenty of headroom to prevent the JVM from running out of space in Old Generation due to an inability for CMS to keep up. Because CMS takes processing resources away from the Directory Server, it is not recommended to set the CMSInitiatingOccupancyFraction at or below the expected database cache size, which would result in the constant running of CMS in the background. See the section on Memory Footprint and Database Cache for a description of determining Old Generation size.

When the CMS collection process cannot keep pace with memory demands in the Old Generation, the JVM will resort to pausing all application processing to allow a full garbage collection. This event, referred to as a stop-the-world pause, does not break existing TCP connections or alter the execution of the Directory Server requests. The goal in tuning CMS is to prevent the occurrence of these pauses. When one does occur, the Directory Server will generate an alert, after the pause, and record the pause time in the error log.

Because determining an ideal CMSInitiatingOccupancyFraction can be difficult, the approach we have taken is to warn if the Directory Server detects a garbage collection pause by generating a recommended value for the occupancy threshold based on the current amount of memory being consumed by the backend caches. Unfortunately, it is not possible for an administrator to determine the ideal occupancy threshold value in advance. Therefore, to warn of any impending garbage collection pauses, the Directory Server calculates a recommended value for the CMSInitiatingOccupancyFraction property and exposes it in the JVM Memory Usage monitor entry in the following attribute:

recommended-cms-initiating-occupancy-fraction-for-current-data-set

Also, when you start the server, you will see an administrative alert indicating the current state of the CMSInitiatingOccupancyFraction and its recommended value.

$ bin/start-server [20/April/2012:10:35:25 -0500] category=CORE severity=NOTICE msgID=458886
msg="PingDirectory Server
            7.3.0.0 (build 20120418135933Z, R6226) starting up" 

... (more output) ...

[20/April/2012:10:35:53 -0500] category=UBID_EXTENSIONS severity=NOTICE 
msgID=1880555580 msg="Memory-intensive Directory Server 
components are configured to consume 71750382 bytes of memory: 
['userRoot local DB backend' currently consumes 26991632 bytes and 
can grow to a maximum of 64323584 bytes, 'changelog cn=changelog backend' 
currently consumes 232204 bytes and can grow to a maximum of 2426798 bytes, 
'Replication Changelog Database' currently consumes 376661 bytes and can 
grow to a maximum of 5000000 bytes]. The configured value of 
CMSInitiatingOccupancyFraction is 36 which is less than the minimum 
recommended value (43) for the server's current configuration. Having 
this value too low can cause the Concurrent Mark and Sweep garbage 
collector to run too often, which can cause a degradation of throughput 
and response time. Consider increasing the CMSInitiatingOccupancyFraction 
value to at least the minimum value, preferably setting it to the 
recommended value of 55 by editing the config/java.properties file, 
running dsjavaproperties, and restarting the Directory Server. 
If the server later detects that this setting actually leads to a 
performance degradation, a separate warning message will be logged. 
If this server has not yet been fully loaded with data, then you 
can disregard this message"

[20/April/2012:10:35:53 -0500] category=CORE severity=NOTICE msgID=458887 
msg="The Directory Server has started successfully"

The Directory Server only makes a recommendation if all of the backends are preloaded and the CMSInitiatingOccupancyFraction JVM property is explicitly set, which is done automatically. For example, if you installed the Directory Server and specified that the database be preloaded (or "primed") at startup, then the Directory Server can make a good recommendation for the Directory Server when a pause occurs. If the backend database cache is not full and has not been preloaded, then the recommended value may be an inaccurately low value.

Note: The generated value for the Directory Server property could change over time with each Directory Server build, Java release, or changes in data set. If the current value is fairly close to the recommended value, then there is no need to change the property unless the server experiences a JVM pause.

If the Directory Server experiences a JVM garbage collection pause, you can retrieve the recommended value from the server, reset the Directory Server property, run dsjavaproperties, and restart the server.