| type=page |
| status=published |
| title=Tuning the Java Runtime System |
| next=tuning-os.html |
| prev=tuning-glassfish.html |
| ~~~~~~ |
| |
| = Tuning the Java Runtime System |
| |
| [[GSPTG00006]][[abeia]] |
| |
| |
| [[tuning-the-java-runtime-system]] |
| == 4 Tuning the Java Runtime System |
| |
| The following topics are addressed here: |
| |
| * link:#abeib[Java Virtual Machine Settings] |
| * link:#gfpzy[Start Options] |
| * link:#glaat[Tuning High Availability Persistence] |
| * link:#abeic[Managing Memory and Garbage Collection] |
| * link:#abeiq[Further Information] |
| |
| [[abeib]][[GSPTG00069]][[java-virtual-machine-settings]] |
| |
| === Java Virtual Machine Settings |
| |
| Each JDK have own set of JVM options useful for tuning. |
| The easiest way is to run the following command and then consult the JDK's |
| documentation to understand all consequences. |
| |
| [source] |
| ---- |
| JAVA_HOME/bin/java -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version |
| ---- |
| |
| [[gfpzy]][[GSPTG00070]][[start-options]] |
| |
| In some situations, performance can be improved by using large page sizes. |
| For Ultrasparc CMT systems, include the `-XX:+UseLargePages` and |
| `-XX:LargePageSizeInBytes=256m` arguments with your JVM tuning. |
| |
| [[glaat]][[GSPTG00071]][[tuning-high-availability-persistence]] |
| |
| === Tuning High Availability Persistence |
| |
| If session `s1` and `s2` need to be replicated to an instance (backup |
| server), the replication module batches the replication messages to be |
| sent to that instance instead of sending separate replication messages. |
| This improves performance. In configurations in which a lot of session |
| replication is performed, you may find better performance by tuning the |
| `org.shoal.cache.transmitter.max.batch.size` system property. This |
| property determines the number of replication messages that constitute |
| one batch. |
| |
| The default value for this property is `20`. You can try setting it as |
| high as `90`, depending on system loads. Like all system properties, |
| this property is set with the `-D` flag in your Java arguments. |
| |
| [[abeic]][[GSPTG00072]][[managing-memory-and-garbage-collection]] |
| |
| === Managing Memory and Garbage Collection |
| |
| The efficiency of any application depends on how well memory and garbage |
| collection are managed. The following sections provide information on |
| optimizing memory and allocation functions: |
| |
| * link:#abeid[Tuning the Garbage Collector] |
| * link:#abeig[Tracing Garbage Collection] |
| * link:#abeih[Other Garbage Collector Settings] |
| * link:#abeii[Tuning the Java Heap] |
| * link:#abeio[Rebasing DLLs on Windows] |
| |
| [[abeid]][[GSPTG00205]][[tuning-the-garbage-collector]] |
| |
| ==== Tuning the Garbage Collector |
| |
| Garbage collection (GC) reclaims the heap space previously allocated to |
| objects no longer needed. The process of locating and removing the dead |
| objects can stall any application and consume as much as 25 percent |
| throughput. |
| |
| Almost all Java Runtime Environments come with a generational object |
| memory system and sophisticated GC algorithms. A generational memory |
| system divides the heap into a few carefully sized partitions called |
| generations. The efficiency of a generational memory system is based on |
| the observation that most of the objects are short lived. As these |
| objects accumulate, a low memory condition occurs forcing GC to take |
| place. |
| |
| The heap space is divided into the old and the new generation. The new |
| generation includes the new object space (eden), and two survivor |
| spaces. The JVM allocates new objects in the eden space, and moves |
| longer lived objects from the new generation to the old generation. |
| |
| The young generation uses a fast copying garbage collector which employs |
| two semi-spaces (survivor spaces) in the eden, copying surviving objects |
| from one survivor space to the second. Objects that survive multiple |
| young space collections are tenured, meaning they are copied to the |
| tenured generation. The tenured generation is larger and fills up less |
| quickly. So, it is garbage collected less frequently; and each |
| collection takes longer than a young space only collection. Collecting |
| the tenured space is also referred to as doing a full generation |
| collection. |
| |
| The frequent young space collections are quick (a few milliseconds), |
| while the full generation collection takes a longer (tens of |
| milliseconds to a few seconds, depending upon the heap size). |
| |
| Other GC algorithms, such as the Concurrent Mark Sweep (CMS) algorithm, |
| are incremental. They divide the full GC into several incremental |
| pieces. This provides a high probability of small pauses. This process |
| comes with an overhead and is not required for enterprise web |
| applications. |
| |
| When the new generation fills up, it triggers a minor collection in |
| which the surviving objects are moved to the old generation. When the |
| old generation fills up, it triggers a major collection which involves |
| the entire object heap. |
| |
| Both HotSpot and Solaris JDK use thread local object allocation pools |
| for lock-free, fast, and scalable object allocation. So, custom object |
| pooling is not often required. Consider pooling only if object |
| construction cost is high and significantly affects execution profiles. |
| |
| [[abeie]][[GSPTG00146]][[choosing-the-garbage-collection-algorithm]] |
| |
| ===== Choosing the Garbage Collection Algorithm |
| |
| The default collector for Java server class machines will optimize for |
| throughput but be tolerant of somewhat long pause times. If you would |
| prefer to have minimal pause times at the expense of some throughput and |
| increased CPU usage, consider using the CMS collector. |
| |
| [[gaclx]][[GSPTG00038]][[to-use-the-cms-collector]] |
| |
| To use the CMS collector |
| |
| Follow this procedure. |
| |
| 1. Make sure that the system is not using 100 percent of its CPU. |
| 2. Configure the CMS collector in the server instance. |
| + |
| To do this, add the following JVM options: |
| |
| * `-XX:+UseConcMarkSweepGC` |
| * `-XX:SoftRefLRUPolicyMSPerMB=1` |
| |
| [[abeif]][[GSPTG00147]][[additional-information]] |
| |
| ===== Additional Information |
| |
| Use the `jvmstat` utility to monitor HotSpot garbage collection. (See |
| link:#abeiq[Further Information].) |
| |
| For detailed information on tuning the garbage collector, see |
| http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html[Java |
| SE 6 HotSpot Virtual Machine Garbage Collection Tuning] |
| (`http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html`). |
| |
| [[abeig]][[GSPTG00206]][[tracing-garbage-collection]] |
| |
| ==== Tracing Garbage Collection |
| |
| The two primary measures of garbage collection performance are |
| throughput and pauses. Throughput is the percentage of the total time |
| spent on other activities apart from GC. Pauses are times when an |
| application appears unresponsive due to GC. |
| |
| Two other considerations are footprint and promptness. Footprint is the |
| working size of the JVM process, measured in pages and cache lines. |
| Promptness is the time between when an object becomes dead, and when the |
| memory becomes available. This is an important consideration for |
| distributed systems. |
| |
| A particular generation size makes a trade-off between these four |
| metrics. For example, a large young generation likely maximizes |
| throughput, but at the cost of footprint and promptness. Conversely, |
| using a small young generation and incremental GC will minimize pauses, |
| and thus increase promptness, but decrease throughput. |
| |
| JVM diagnostic output will display information on pauses due to garbage |
| collection. If you start the server in verbose mode (use the command |
| `asadmin start-domain --verbose` domain), then the command line argument |
| `-verbose:gc` prints information for every collection. Here is an |
| example of output of the information generated with this JVM flag: |
| |
| [source] |
| ---- |
| [GC 50650K->21808K(76868K), 0.0478645 secs] |
| [GC 51197K->22305K(76868K), 0.0478645 secs] |
| [GC 52293K->23867K(76868K), 0.0478645 secs] |
| [Full GC 52970K->1690K(76868K), 0.54789968 secs] |
| ---- |
| |
| On each line, the first number is the combined size of live objects |
| before GC, the second number is the size of live objects after GC, the |
| number in parenthesis is the total available space, which is the total |
| heap minus one of the survivor spaces. The final figure is the amount of |
| time that the GC took. This example shows three minor collections and |
| one major collection. In the first GC, 50650 KB of objects existed |
| before collection and 21808 KB of objects after collection. This means |
| that 28842 KB of objects were dead and collected. The total heap size is |
| 76868 KB. The collection process required 0.0478645 seconds. |
| |
| Other useful monitoring options include: |
| |
| * `-XX:+PrintGCDetails` for more detailed logging information |
| * `-Xloggc:file` to save the information in a log file |
| |
| [[abeih]][[GSPTG00207]][[other-garbage-collector-settings]] |
| |
| ==== Other Garbage Collector Settings |
| |
| To specify the attributes for the Java virtual machine, use the |
| Administration Console and set the property under config-name > JVM |
| settings (JVM options). |
| |
| [[glgkm]][[GSPTG00148]][[setting-the-maximum-permanent-generation]] |
| |
| ===== Setting the Maximum Permanent Generation |
| |
| For applications that do not dynamically generate and load classes, the |
| size of the permanent generation does not affect GC performance. For |
| applications that dynamically generate and load classes (for example, |
| JSP applications), the size of the permanent generation does affect GC |
| performance, since filling the permanent generation can trigger a Full |
| GC. Tune the maximum permanent generation with the `-XX:MaxPermSize` |
| option. |
| |
| [[glglk]][[GSPTG00149]][[disabling-explicit-garbage-collection]] |
| |
| ===== Disabling Explicit Garbage Collection |
| |
| Although applications can explicitly invoke GC with the `System.gc()` |
| method, doing so is a bad idea since this forces major collections, and |
| inhibits scalability on large systems. It is best to disable explicit GC |
| by using the flag `-XX:+DisableExplicitGC`. |
| |
| |
| [NOTE] |
| ==== |
| On Windows systems, setting the `-XX:+DisableExplicitGC` option might |
| prevent the renaming or removal of open application files. As a result, |
| deployment, redeployment, or other operations that attempt to rename or |
| delete files might fail. |
| |
| Application files can remain open because the files have been used by |
| class loaders to find classes or resources, or have been opened |
| explicitly by {productName} or application code but never explicitly |
| closed. On Windows systems, open files cannot be renamed or deleted. To |
| overcome this limitation, {productName} uses the `System.gc()` method |
| to garbage collect the Java object that corresponds to an open file. |
| When the Java object that corresponds to an open file is garbage |
| collected, the object's `finalize` method closes the open channel to the |
| file. {productName} can then delete or rename the file. |
| ==== |
| |
| |
| [[glglr]][[GSPTG00150]][[setting-the-frequency-of-full-garbage-collection]] |
| |
| ===== Setting the Frequency of Full Garbage Collection |
| |
| {productName} uses RMI in the Administration module for monitoring. |
| Garbage cannot be collected in RMI-based distributed applications |
| without occasional local collections, so RMI forces a periodic full |
| collection. Control the frequency of these collections with the property |
| `-sun.rmi.dgc.client.gcInterval`. For example, |
| `- java -Dsun.rmi.dgc.client.gcInterval=3600000` specifies explicit |
| collection once per hour instead of the default rate of once per minute. |
| |
| [[abeii]][[GSPTG00208]][[tuning-the-java-heap]] |
| |
| ==== Tuning the Java Heap |
| |
| This section discusses topics related to tuning the Java Heap for |
| performance. |
| |
| * link:#abeij[Guidelines for Java Heap Sizing] |
| * link:#abeik[Heap Tuning Parameters] |
| |
| [[abeij]][[GSPTG00151]][[guidelines-for-java-heap-sizing]] |
| |
| ===== Guidelines for Java Heap Sizing |
| |
| Maximum heap size depends on maximum address space per process. The |
| following table shows the maximum per-process address values for various |
| platforms: |
| |
| [[sthref10]][[gacna]] |
| |
| Table 4-1 Maximum Address Space Per Process |
| |
| [width="100%",cols="<62%,<38%",options="header",] |
| |=== |
| |Operating System |Maximum Address Space Per Process |
| |Oracle/Redhat/Ubuntu Linux 32-bit |4 GB |
| |Oracle/Redhat/Ubuntu Linux 64-bit |Terabytes |
| |Windows XP/2008/7 |2 GB |
| |Solaris x86 (32-bit) |4 GB |
| |Solaris 32-bit |4 GB |
| |Solaris 64-bit |Terabytes |
| |=== |
| |
| |
| Maximum heap space is always smaller than maximum address space per |
| process, because the process also needs space for stack, libraries, and |
| so on. To determine the maximum heap space that can be allocated, use a |
| profiling tool to examine the way memory is used. Gauge the maximum |
| stack space the process uses and the amount of memory taken up libraries |
| and other memory structures. The difference between the maximum address |
| space and the total of those values is the amount of memory that can be |
| allocated to the heap. |
| |
| You can improve performance by increasing your heap size or using a |
| different garbage collector. In general, for long-running server |
| applications, use the Java SE throughput collector on machines with |
| multiple processors (`-XX:+AggressiveHeap`) and as large a heap as you |
| can fit in the free memory of your machine. |
| |
| [[abeik]][[GSPTG00152]][[heap-tuning-parameters]] |
| |
| ===== Heap Tuning Parameters |
| |
| You can control the heap size with the following JVM parameters: |
| |
| * ``-Xms``value |
| * ``-Xmx``value |
| * ``-XX:MinHeapFreeRatio=``minimum |
| * ``-XX:MaxHeapFreeRatio=``maximum |
| * ``-XX:NewRatio=``ratio |
| * ``-XX:NewSize=``size |
| * ``-XX:MaxNewSize=``size |
| * `-XX:+AggressiveHeap` |
| |
| The `-Xms` and `-Xmx` parameters define the minimum and maximum heap |
| sizes, respectively. Since GC occurs when the generations fill up, |
| throughput is inversely proportional to the amount of the memory |
| available. By default, the JVM grows or shrinks the heap at each GC to |
| try to keep the proportion of free space to the living objects at each |
| collection within a specific range. This range is set as a percentage by |
| the parameters `-XX:MinHeapFreeRatio=`minimum and |
| `-XX:MaxHeapFreeRatio=`maximum; and the total size bounded by `-Xms` and |
| `-Xmx`. |
| |
| Set the values of `-Xms` and `-Xmx` equal to each other for a fixed heap |
| size. When the heap grows or shrinks, the JVM must recalculate the old |
| and new generation sizes to maintain a predefined `NewRatio`. |
| |
| The `NewSize` and `MaxNewSize` parameters control the new generation's |
| minimum and maximum size. Regulate the new generation size by setting |
| these parameters equal. The bigger the younger generation, the less |
| often minor collections occur. The size of the young generation relative |
| to the old generation is controlled by `NewRatio`. For example, setting |
| `-XX:NewRatio=3` means that the ratio between the old and young |
| generation is 1:3, the combined size of eden and the survivor spaces |
| will be fourth of the heap. |
| |
| By default, the {productName} is invoked with the Java HotSpot Server |
| JVM. The default `NewRatio` for the Server JVM is 2: the old generation |
| occupies 2/3 of the heap while the new generation occupies 1/3. The |
| larger new generation can accommodate many more short-lived objects, |
| decreasing the need for slow major collections. The old generation is |
| still sufficiently large enough to hold many long-lived objects. |
| |
| To size the Java heap: |
| |
| * Decide the total amount of memory you can afford for the JVM. |
| Accordingly, graph your own performance metric against young generation |
| sizes to find the best setting. |
| * Make plenty of memory available to the young generation. The default |
| is calculated from `NewRatio` and the `-Xmx` setting. |
| * Larger eden or younger generation spaces increase the spacing between |
| full GCs. But young space collections could take a proportionally longer |
| time. In general, keep the eden size between one fourth and one third |
| the maximum heap size. The old generation must be larger than the new |
| generation. |
| |
| For up-to-date defaults, see |
| http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html[Java |
| HotSpot VM Options] |
| (`http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html`). |
| |
| [[GSPTG00032]][[fxxpw]] |
| Example 4-1 Heap Configuration on Solaris |
| |
| This is an exmple heap configuration used by {productName} on Solaris |
| for large applications: |
| |
| [source] |
| ---- |
| -Xms3584m |
| -Xmx3584m |
| -verbose:gc |
| -Dsun.rmi.dgc.client.gcInterval=3600000 |
| ---- |
| |
| [[abeil]][[GSPTG00031]][[survivor-ratio-sizing]] |
| |
| Survivor Ratio Sizing |
| |
| The `SurvivorRatio` parameter controls the size of the two survivor |
| spaces. For example, `-XX:SurvivorRatio=6` sets the ratio between each |
| survivor space and eden to be 1:6, each survivor space will be one |
| eighth of the young generation. The default for Solaris is 32. If |
| survivor spaces are too small, copying collection overflows directly |
| into the old generation. If survivor spaces are too large, they will be |
| empty. At each GC, the JVM determines the number of times an object can |
| be copied before it is tenured, called the tenure threshold. This |
| threshold is chosen to keep the survivor space half full. |
| |
| Use the option `-XX:+PrintTenuringDistribution` to show the threshold |
| and ages of the objects in the new generation. It is useful for |
| observing the lifetime distribution of an application. |
| |
| [[abeio]][[GSPTG00209]][[rebasing-dlls-on-windows]] |
| |
| ==== Rebasing DLLs on Windows |
| |
| When the JVM initializes, it tries to allocate its heap using the `-Xms` |
| setting. The base addresses of {productName} DLLs can restrict the |
| amount of contiguous address space available, causing JVM initialization |
| to fail. The amount of contiguous address space available for Java |
| memory varies depending on the base addresses assigned to the DLLs. You |
| can increase the amount of contiguous address space available by |
| rebasing the {productName} DLLs. |
| |
| To prevent load address collisions, set preferred base addresses with |
| the rebase utilty that comes with Visual Studio and the Platform SDK. |
| Use the rebase utility to reassign the base addresses of the {productName} DLLs to prevent relocations at load time and increase the |
| available process memory for the Java heap. |
| |
| There are a few {productName} DLLs that have non-default base |
| addresses that can cause collisions. For example: |
| |
| * The `nspr` libraries have a preferred address of 0x30000000. |
| * The `icu` libraries have the address of 0x4A?00000. |
| |
| Move these libraries near the system DLLs (`msvcrt.dll` is at |
| `0x78000000`) to increase the available maximum contiguous address space |
| substantially. Since rebasing can be done on any DLL, rebase to the DLLs |
| after installing the {productName}. |
| |
| [[gacmt]][[GSPTG00039]][[to-rebase-the-glassfish-servers-dlls]] |
| |
| ===== To rebase the {productName}'s DLLs |
| |
| [[sthref11]] |
| |
| Before You Begin |
| |
| To perform rebasing, you need: |
| |
| * Windows 2000 |
| * Visual Studio and the Microsoft Framework SDK rebase utility |
| |
| 1. Make as-install\ `bin` the default directory. |
| + |
| [source] |
| ---- |
| cd as-install\bin |
| ---- |
| |
| 2. Enter this command: |
| + |
| [source] |
| ---- |
| rebase -b 0x6000000 *.dll |
| ---- |
| |
| 3. Use the `dependencywalker` utility to make sure the DLLs were |
| rebased correctly. |
| + |
| For more information, see the http://www.dependencywalker.com[Dependency |
| Walker website] (`http://www.dependencywalker.com`). |
| |
| 4. Increase the size for the Java heap, and set the JVM Option |
| accordingly on the JVM Settings page in the Admin Console. |
| |
| 5. Restart the {productName}. |
| |
| [[GSPTG00033]][[fxxpz]] |
| Example 4-2 Heap Configuration on Windows |
| |
| This is an example heap configuration used by {productName} |
| for heavy server-centric applications, on Windows, as set in the |
| `domain.xml` file. |
| |
| [source,xml] |
| ---- |
| <jvm-options> -Xms1400m </jvm-options> |
| <jvm-options> -Xmx1400m </jvm-options> |
| ---- |
| |
| [[sthref12]] |
| |
| See Also |
| |
| For more information on rebasing, see |
| http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tools/tools/rebase.asp[MSDN |
| documentation for rebase utility] |
| (`http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tools/tools/rebase.asp`). |
| |
| [[abeiq]][[GSPTG00073]][[further-information]] |
| |
| === Further Information |
| |
| For more information on tuning the JVM, see: |
| |
| * http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html[ |
| Java HotSpot VM Options] |
| (`http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html`) |
| * http://www.oracle.com/technetwork/java/hotspotfaq-138619.html[ |
| Frequently Asked Questions About the Java HotSpot Virtual Machine] |
| (`http://www.oracle.com/technetwork/java/hotspotfaq-138619.html`) |
| * http://www.oracle.com/technetwork/java/javase/tech/index-jsp-136373.html[ |