Java Virtual Machines (JVMs) externalize multiple tuning knobs which may be used to improve WebSphere Business Integration application performance. These knobs control issues related to garbage collection, heap size, threading, and locking. Because the ICS server and its components (maps, collaborations) as well as most of the adapters are written in Java, the performance of the JVM has a significant impact on the performance delivered by an ICS application.
This section addresses potential issues with garbage collection, heap size, and thread stack size. The following URL provides a useful summary of JVM options: http://java.sun.com/docs/hotspot/VMOptions.html
The following URL provides a useful FAQ about the HotSpot Engine: http://java.sun.com/docs/hotspot/PerformanceFAQ.html#20
For a detailed description of the IBM JVM the reader should consult the Java Performance issue of the "IBM Systems Journal", Vol. 1, 2000: http://www.research.ibm.com/journal/sj39-1.html
Garbage collection is the process of freeing unused objects in the JVM so that portions of the heap can be reused.
Garbage collection occurs when there is a request for memory, and the request cannot be readily satisfied from the free memory available in the heap (allocation failure). Garbage collection also occurs when a Java class library System.gc() call is made. In this case garbage collection occurs immediately and synchronously.
While the function provided by the SUN HotSpot and IBM garbage collectors is the same, the underlying technology is different. For both JVMs garbage collection takes place in three phases: mark, sweep, and an optional compact phase.
The implementation of the garbage collection phases is different because the Sun HotSpot engine is a generational collector and the IBM JVM is not. A detailed discussion of the HotSpot generational collector can be found at the following URL: http://java.sun.com/docs/hotspot/gc/index.html
With the IBM JVM, the full heap is consumed before a garbage collection is triggered. The first phase is to mark all referenced objects in the region being collected, which leaves all un-referenced objects unmarked and the space they occupy free to be collected and reused. Following the mark phase, free chunks of memory are added to a freelist. This phase is referred to as sweeping. For performance reasons, the IBM JVM only frees chunks of heap space greater than 512 bytes.
Following the sweep phase, a compact phase is sometimes performed. The compact phase moves objects closer together to create larger contiguous free chunks. Because compaction is time-consuming, avoid it when possible For most System.gc() calls compaction is performed. The IBM JVM has been optimized to avoid compaction.
The following table explains which phases of garbage collection are multi-threaded and which are concurrent. Concurrent means the process runs while the application threads continue to execute. If the process is not concurrent it means that the program pauses during that phase of garbage collection.
Table 54. JVM Release Mark Sweep Compact
JVM release | Type | Mark | Sweep | Compact |
---|---|---|---|---|
Sun HotSpot 1.3.1 | Multithreaded | No | No | No |
Sun HotSpot 1.3.1 | Concurrent | No | No | No |
IBM JVM 1.3.1 | Multithreaded | Yes | Yes | No |
IBM JVM 1.3.1 | Concurrent | Optional | No | No |
A verbosegc trace prints garbage collection actions and statistics to stderr. The verbosegc trace is activated by using the Java run time option of -verbose:gc. Output from -verbose:gc is different for the Sun HotSpot and IBM JVMs. Below are sample output from a verbosegc trace with embedded explanations of key pieces of information for both an IBM JVM and Sun HotSpot.
<AF[8]: Allocation Failure. need 1572744 bytes <-amount of memory requested, 5875 ms since last AF> <AF[8]: managing allocation failure, action=1 (23393256 <-free at alloc failure)/131070968 <- heapsize) (2096880/3145728)> <GC: Tue Dec 18 17:32:26 2001 <GC(12): freed 75350432 bytes in 168 ms <- duration of GC, 75% free (100840568 <-free)/134216696 <- total heapsize)> <GC(12): mark: 129 ms, sweep: 39 ms, compact: 0 ms <-compact did not run> <GC(12): refs: soft 0 (age >= 32), weak 0, final 0 <-no finalizers, phantom 0> <AF[8]: completed in 203 ms>
[GC 325816K->83372K(776768K), 0.2454258 secs <-duration of GC] [Full GC 267628K->83769K <- live data (776768K <-size of heap), 1.8479984 secs]
This section contains guidelines for determining the appropriate Java heap size for most WBI configurations.
For many applications, the default heap size setting for the IBM JVM is sufficient for good performance. In general, the HotSpot JVM default Heap and Nursery sizes are too small. To set the optimal heap size for the IBM JVM on AIX, follow these guidelines.
In order to effectively use rate-trigger heap growth just set the -ms to 64MB or 96MB, and the -mx to 256-512MB. Ensure that -mx does not force the heap to page. The JVM will try to control the GC time by growing and shrinking the heap. The output from -verbose:gc monitors the GC actions.
A similar process can be used to set HotSpot heaps. In addition to setting the minimum and maximum heap size, one should also increase the Nursery size to approximately 1/4 of the heap size.
Once the heap sizes are set, verbose:gc traces monitor the GC actions. If the percentage of time in GC is too high and the heap has grown to its maximum, increase -mx.
Each running Java program has an associated heap. If the sum of all of the Java heap sizes and all other usages of virtual memory exceeds the size of physical memory, then the heap page, causing performance to degrade. To minimize the paging, use the following guidelines:
The java.lang.OutofMemoryError is used by the JVM in a variety of circumstances. The exception occurs if there is not enough heap space for an object in the heap, or if other resources outside the Java heap have been exhausted.
Read the output from java.lang.OutofMemoryError to see if the problem is due to a lack of memory in the heap. If so, increase the size of the heap.
If the heap appears to be large enough, check the finalized count from the -verbose:gc. If the count appears high, resources outside the heap might be held by objects within the heap and cleaned by finalizers. Reduce the size of the heap and increase the frequency with which finalizers are run.
The IBM JVM threading and synchronization components are based upon the AIX Posix compliant Pthread implementation. The following environments variables have been found to improve Java performance in many situations and have been used for the benchmarks in this document. The variables control the mapping of Java threads to AIX Native threads, turn off mapping information, and allow for spinning on Mutex locks.
More information on AIX specific Java tuning information can be found at: http://tesch.aix.dfw.ibm.com/java/perftips.html
The Sun HotSpot JVM can be configured to run as a server or as a client. When configured as a server the JIT (Just-In-Time Compiler) uses extra processor cycles and memory to create more highly optimized code. Since the ICS is a long running process the extra time and memory spent JITting at initial instantiation is well worth the increased performance during run time.
Therefore, when using the Sun HotSpot JVM, the ICS should always be run as a server. To do this, the -server parameter is added to the invocation of the ICS process.
As mentioned in the section on ICS threading, Java threads consume memory in the heap. In addition, the threads themselves use virtual memory for their thread stacks. If a configuration is using an excessive number of threads, memory in either place may become a problem. The JVM allows a user to configure the amount of virtual memory set aside for the thread stack. The default thread stack size is different depending on the JVM version and the operating system. However, the mechanism to set the value is the same. To set the thread stack size to 128KB, the parameter -ss128k is passed in on the invocation of the JVM. Care should be taken not to set this value to small. It is recommend that at least 128KB be given to each thread stack, although the system may operate successfully with a lower setting.
Refer to the following SAP notes for resolving memory related issues: