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 8.0.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.
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.