(Dist) Sun HotSpot JVM tuning parameters (Solaris and HP-UX)
Tune a Sun HotSpot JVM is an iterative process where the JVM configuration is developed, data is gathered, primarily the verbosegc data, and then analyzed. Any configuration revisions are then applied on the next cycle.
Even though there are many Sun HotSpot JVM parameters, the following parameters have been identified as central to tuning. Which of these parameters we modify depends on the configuration choices. Therefore, in addition to reviewing these parameter descriptions, we can read about tuning Sun HotSpot Java Virtual Machines (Solaris and HP-UX) for a complete understanding of the JVM tuning methodology.
There is a standard form by which all Sun HotSpot options are specified. Understanding this form can help you avoid problems with transcribing options, interpreting instructions, and avoiding the potential confusion caused by the JVM rejecting an option, and then refusing to start.
We should be particularly concerned with the Sun HotSpot options that are particular to the implementation of the Sun HotSpot JVM, starting with the -XX option, rather than to standard or portable VM options, such as -X option or - option. The majority of these options are boolean valued, meaning they are set to either true or false. These settings either enable or disable a feature. The following standard form is used to enable an option, which is what you typically do when we change the setting of an option during the tuning process:
-XX:+ optionThe following standard form is used to disable an option, which we will do less frequently:
-XX:- option
- The use of a plus sign or a minus sign should immediately follows the colon. Otherwise the option typically requires a value, and appears more like the assignment of a value because it has an option=value format.
- As stated on the SUN website, the -XX Hotspot options are subject to change without notice in subsequent releases of the JDK. Therefore, before specifying an option, we should verify that it is supported for the version of the JDK that we are running on the system.
When determining which option to use, the name of the option typically describes the action that occurs if the option is enabled. The default value for most options leave the feature disabled. Therefore, if we disable an option already disabling a feature, it is possible to cause a double-negative situation. This is particularly true with options that have names that begins with the word Disable. For example, the default setting for the DisableExplicitGC option causes JVM to honor Explicit garbage collection requests. Therefore, we would normally want to enable this option by specifying a plus sign in front of this option. The plus sign has the affect of disabling the honoring of explicit garbage collection requests, which is what the name of the options implies. With options, such as the DisableExplicitGC option, it is rare to encounter the setting -XX:-DisableExplicitGC because this setting equates to specifying the default action.
In circumstances where the name of the option includes the term Use, the option typically makes more sense either for the enablement or disablement of that feature and the sense of the plus or minus sign is usually more intuitive.
Where a value needs to be specified, the option appears like an assignment with an equal sign between the option and the setting. In this situation, the option expects an appropriate number value to immediately follow the equal sign, without any blank spaces between the equal sign and the number. The value can often accept standard abbreviations, such as k for kilobytes, m for megabytes, and g for gigabytes, where it is appropriate to specify these values. The virtual machine performs only limited validation of such parameters, and, where invalid, typically produces an error message that indicates that the virtual machine cannot start.
Tune HotSpot Java virtual machines (Solaris & HP-UX)
-Xmx (Maximum Java Heap size)
Tune this parameter, in conjunction with the -XX:MaxPermSize parameter, to provide enough Java heap memory. When we specify a value for the maximum Java heap size for object storage in the Java heap, we should consider that the peak resource demands that are necessary for processing the peak input volumes designed to be handled by the system.
By contrast, the initial minimum size of the Java heap, specified using the -Xms parameter, should reflect the sizing of the Java heap needed to accommodate the persistent data that arises from the normal operation of the system under a routine steady-state input load. Such a resource request ensures an efficient system startup, where just the amount of storage is claimed to permit quick initialization without needing many garbage collection cycles to increase heap capacity. Thereafter, the working size capacity of the Java heap varies between the normal capacity known to accommodate a routine steady-state workload, and the systems design peak size, and any variations in heap capacity should reflect changes in the systems inputs, such as a burst of activity, or the increase of workload.
The working size capacity of the Java heap is considered useful information about the running state of the system. Tuning the initial minimum size of the Java heap should only involve optimizing system startup. Setting minimum and maximum heap sizes to the same value fixes the Java heap and constrains the recovery options of the JVM for its housekeeping of the Java heap. This type of setup can cause performance penalties and poor utilization of Java heap resources.
-XX:+AggressiveHeap
Use this parameter if we are using the default throughput/parallel scavenge collector with built-in tuning enabled. The JVM can attempt to aggressively tune the parameters of its tuning algorithm based on using all the resources of the operating system on which we are running. In situations where a single product process is executing using all of the resources of the operating system, use of this option to determine if the JVM can deliver satisfactory results. Using this option while testing JVM results should reduce your tuning effort.
-XX:CMSInitiatingOccupancyFraction=75
Configure this parameter if we are using the concurrent low-pause mark-sweep collector. This option is used to control CMS. It sets the triggering condition for when the dedicated background thread engages to conduct garbage collection on the tenured region of the heap. Unlike other garbage collection modes, the garbage collection action does not wait for an allocation to fail. Instead the objective is to trigger the garbage collection to recover sufficient space before the allocation arises that would otherwise have failed. The principle trigger is based on the percentage utilization of the Java heap, and defaults to about 70%. The default value typically ensures that CMS cycles start sufficiently, although this frequency might be higher than necessary.
However, with only a very small eden region, and no use of the survivor spaces, there is barely any opportunity for objects to age, such that the generational garbage collection support can collect short-lived objects. For systems that benefit from generational garbage collection, by producing many quite short-lived objects, the CMS defaults deny the opportunity to exploit the generational support for which the Sun HotSpot structure is primarily designed. For only a modest investment of resources in the young generation survivor spaces, and a decent eden region, to re-enable full generational garbage collection action will probably only cause an invasive pause of a second, or less, keeping the promotion of aged objects into the tenured region low. This condition gives you the full benefit of the free compaction of surviving content as objects age, and provides maximum opportunity for the CMS thread to collect the tenured region, even with large heaps.
-XX:+DisableExplicitGC
This option disable explicit garbage collection to eliminate any unnecessary or mistimed major garbage collection cycles that might be introduced in the software components of the system.
IBM recommends that developers avoid the use of System.gc() calls to cause programmer-initiated, full compaction garbage collection cycles, because such calls can interfere with tuning the resources and garbage collection for a entire application system. If we are striving to meet demanding pause time requirements, and want to prevent programmer initiated garbage collection calls, then use of this option must be strongly considered because this option causes explicit System.gc() calls to be ignored.
-XX:MaxNewSize= and -XX:NewSize=
Use these parameters if we are using the default throughput/parallel scavenge collector, but have decided to manually tune this scavenge collector, instead of using the built-in tuning that the -XX:+UseAdaptiveSizePolicy parameter provides. The current young generation size is bound to be greater than or equal to the initial or minimum young generation size, as specified on the -XX:NewSize parameter. This size is less than or equal to the value specified for the maximum young generation, as specified on the -XX:MaxNewSize parameter.
Certain circumstances might suggest that you constrain the amount of the heap that is considered by generational garbage collection, as determined by the -XX:NewRatio parameter, typically limiting the maximum scope of the young generation, and occasionally limiting the minimum size. For example, setting the limit of a large object that might be subject to generational garbage collection, or to limit the maximum amount of memory that is typically in use beyond the set of persistent objects with long lifetimes, we might need to set a maximum size for the young generation heap. Specifying a minimum size, for the section of the heap used for young generation objects, typically accompanies tuning the use of survivor spaces, which is usually of secondary importance, but must satisfy meeting the constraints for the minimum resources in the Java heap, as specified on the -Xms parameter.
Unless we are striving for a specific behavior within generational garbage collection, it should be unnecessary to specify either minimum or maximum separately from the use of the NewRatio option. The reasons for setting either the maximum or minimum values are typically different. Seldom do these settings need to be set to the same value, even though there is a shorthand for setting and fixing the size of the young generation section, using the -Xmn parameter. However, an inappropriate configuration risks the loss of the benefits of generational garbage collection entirely.
-XX:MaxPermSize (Permanent region)
Tune this parameter in conjunction with the -Xmx parameter to provide enough Java heap memory. The permanent region is employed to store all the class code and class-like data, such as interned strings.
The permanent region must be large enough to accommodate all of the classes that might be concurrently loaded together. Determining an appropriate size for this region might be confusing, because this region of the heap is smaller, expands more slowly, and is specifically employed for class-like objects, and it is commonly observed to be utilized at 99-100% of its current capacity. Therefore, we must be careful how you interpret out-of-memory events. We should always verify that this region is maximally expanded before providing this region with more resources.
In any Java EE based system, with its heavy use of application class loaders, we should avoid using the -Xnoclassgc parameter because this parameter prevents garbage collection of this critical region of the heap, effectively creating a memory leak of class data. For a development system where we are frequently deploying changing class content, we should significantly oversize this region. We should also regularly restart this system to prevent old versions of dormant code from accumulating within currently used, and otherwise unreleaseable class loaders.
-XX:MaxTenuringThreshold=number-of-collections
Configure this parameter when using the concurrent low-pause mark-sweep collector. This parameter controls the promotion of the objects from the new generation section to the old generation section by specifying the number of collections during which an object remains in the new generation section before being moved to the old generation section. 8 is the default value.
-XX:NewRatio=2
Use this parameter if we are using the default throughput/parallel scavenge collector, but have decided to manually tune this scavenge collector, instead of using the built-in tuning that the -XX:+UseAdaptiveSizePolicy parameter provides.
The Java heap is divided into two sections where objects are stored. One of the sections is where generational garbage collection occurs, and is where young generation objects reside. The other section, which comprises the rest of the heap, is called the tenured heap, and is where the old or long-lived objects reside. This option sizes the young generation region that supports generational garbage collection, in proportion to the overall heap capacity. The current young generation size is bound to be greater-than or equal to the initial or minimum young generation size, as specified on the -XX:NewSize parameter. This size is less-than or equal to the value specified for the maximum young generation, as specified on the -XX:MaxNewSize parameter. The young generation size is maintained as a ratio to the tenured region, as determined by the current capacity of the main Java heap. The default value of 2 means that the tenured region is twice the size of the young generation region, which means that the young generation is one third of the entire Java heap.
This default value typically delivers good generational garbage collection performance, which is the typical goal of tuning the Sun HotSpot JVM. However, other strategies exist. For example, we might want to increase the proportion of the heap where generational garbage collection is conducted. If we decide to change the proportion, remember that there is a limit as to how much of the heap can reasonably be maintained by generational garbage collection, and if that limit is exceeded, all generational garbage collection might be lost because garbage collection cycles will become major garbage collection cycles over the whole heap instead of the desired minor garbage collection cycles that consider just the generational part of the heap.
2 is the default value for a server running in VM mode.
-XX:NewSize=128m
Configure this parameter if we are using the concurrent low-pause mark-sweep collector. The current young generation size is bound to be greater than or equal to the initial or minimum young generation size, as specified on the -XX:NewSize parameter. One of the difficulties for tuning with CMS is that the worst case garbage collection times, which occurs when the CMS cycle aborts, might take several seconds, which is especially costly for a system that is employing CMS as a way to avoid long pauses.
Consequently, service level agreements might dictate the use of CMS. In this situation tuning must err on the cautious side to ensure that CMS is given every opportunity to succeed. CMS succeeds only when its anticipatory trigger ensures the CMS cycle starts early enough to always ensure that sufficient free resources are available before they are demanded. If the CMS collector is unable to finish before the tenured generation fills up, the collection is completed by pausing the application threads, which is called a full collection. Full collections are a sign that further tuning is required to the CMS collector to make its operation better suit the application.
-XX:+PrintTenuringDistribution
This option is a garbage collection logging option which enables the printing of information regarding the age of the objects, tenuring information, as they age through the survivor spaces.
-XX:SurvivorRatio=
Use this parameter if we are using the default throughput/parallel scavenge collector, but have decided to manually tune this scavenge collector, instead of using the built-in tuning that the -XX:+UseAdaptiveSizePolicy parameter provides, or if we are trying to tune the concurrent low pause collector.
The generational garbage collection action concerns dividing short-lived objects from longer lived ones. Only those objects that continue in use need to be preserved in the heap. The young generation region that hosts generational garbage collection includes further internal structure. It includes a large eden region where objects are initially allocated, and smaller survivor spaces where objects, that have longer lifetimes, reside. The SurvivorRatio sizes these regions in terms of how large the eden region is relative to the smaller survivor space. Sizing the survivor spaces is typically of secondary importance, because the volume of objects that might benefit from optimization varies greatly by application. However, typically we should decrease this value from the default value of 25, to something like 8.
Any changes to this parameter should be justified through an analysis of the data concerning the tenuring. Use the -XX:+PrintTenuringDistribution parameter to obtain this data
-XX:SurvivorRatio= option is incompatible with the JVM parameter -XX:+UseAdaptiveSizePolicy. Please use either one according to your situation.
-XX:TargetSurvivorRatio=
Use this parameter if we are using the default throughput/parallel scavenge collector, but have decided to manually tune this scavenge collector, instead of using the built-in tuning that the -XX:+UseAdaptiveSizePolicy parameter provides.
This parameter encourages the JVM to increase the percentage utilization of the survivor spaces, thereby avoiding premature promotion, if possible, and maximizing the chance for objects to be collected from the young generation. The default is 50. Better utilization of these regions might be achieved if we set this parameter to 90.
-XX:+UseAdaptiveSizePolicy
Use this parameter to enable the built-in tuning with the default throughput/parallel scavenge collector default throughput/parallel scavenge collector.
In addition to the automatic operating system detection, Sun includes a tuning algorithm that attempts to autonomically tune the JVM to optimize the throughput goal and the efficiency of the throughput collection strategy. This tuning algorithm is turned on by default, and is explicitly engaged using the -XX:+UseAdaptiveSizePolicy parameter. This tuning algorithm should typically achieve satisfactory results for the majority of application workloads, saving you from having to perform additional tuning efforts. However we should still test this algorithm for our workload and verify that it meets your throughput requirements before using it in a production environment.
-XX:+UseConcMarkSweepGC
Use this parameter to enable the concurrent low-pause mark-sweep collector. This garbage collection mode reconfigures the generational garbage collection so that your out-of-the-box the system minimizes the invasive pauses introduced by having to collect the young generation content.
This parameter also minimizes the extent of the young generation, or eden region. Server-class systems typically detect the availability of multiple processors, and attempt to collect the young generation in parallel, in an attempt to deliver absolutely the minimum pause possible, even if there exists only a limited amount of work available, giving little advantage for the use of multiple threads after the coordination overhead. To offset the work no longer being performed by generational garbage collection, it is typically necessary to increase the resources committed to the main heap by about ten to thirty percent, as compared to the throughput collector settings.
-XX:+UseParallelGC
Use this parameter to enable the default throughput/parallel scavenge collector.
The default garbage collection mode of a server JVM is to adopt the throughput collector that conducts the minor garbage collections over the young generation in parallel as a foreground stop-the-world task. This collector can be enabled explicitly through the use of the -XX:+UseParallelGC parameter. Goals, other than throughput, can be specified. However, the penalty for not achieving such goals can be quite severe, and might cause a fatal out-of-memory error.