3 Long Latencies

Long latencies might manifest, for example, as single transactions that time out in a transaction-based application while the overall performance is good. The problem usually is uneven performance and nondeterministic latencies.

This chapter includes the following topics:

3.1 Tune the JVM to Reduce Latency

Long latencies might indicate that the application is not tuned for short and deterministic pause times. Before engaging in time-consuming troubleshooting and mitigation tasks, try tuning the JVM to optimize for short pause times. For information about tuning the JVM for short pause times, see the Oracle JRockit Performance Tuning Guide.

Note that there are trade-offs exist between low latencies and high overall application throughput.

  • High latencies that cause transactions to time out are often caused by pauses for garbage collection. To reduce the individual garbage-collection pause times the garbage collector runs in a mostly concurrent mode; that is, the garbage collection is, mostly, performed while the Java threads are still running. This causes some additional work for the garbage collector, which has to keep track of changes during the concurrent phases of the garbage collection. The garbage collections are also less efficient because objects that are allocated during the concurrent garbage collection, are not garbage collected until the next garbage collection cycle. This can force the JVM to collect garbage more frequently.

  • If you have disabled or limited compaction by using the -XXcompaction command-line option, to reduce the pause times caused by compaction, the heap might become fragmented. (You can analyze fragmentation by using the Flight Recorder tool.)

You can increase the overall throughput while keeping the latencies low by allowing longer garbage collection pauses or by manually tuning the garbage collection. For more information, see the Oracle JRockit Performance Tuning Guide.

3.2 Troubleshooting Latency Issues

This section provides information to troubleshoot latency issues related mostly to concurrent garbage collection; for example, -Xgc:deterministic and -Xgc:pausetime.

3.2.1 GC Trigger Value Keeps Increasing

The garbage collection trigger (gctrigger) value is the amount of free heap space that should be available when a concurrent garbage collection starts, to allow the Java threads to continue allocating objects during the entire garbage collection. The gctrigger value changes at run time, to avoid situations where the heap becomes full during concurrent garbage collection.

Monitor the gctrigger value by using the output of the -Xverbose:memdbg option or by using the Flight Recorder tool.

  • A continuously increasing gctrigger value indicates that the load on the application is too high for the concurrent garbage collector. Decrease the load on the application.

  • A continuously increasing gctrigger value could also indicate that the Java heap size is too small; the behavior might improve if you increase the heap size.

3.2.2 GC Reason for Old Collections is Failed Allocations

Monitor the garbage collection reasons for the old collections by using either the -Xverbose:memdbg option or the Flight Recorder tool. The normal garbage collection reason for a mostly concurrent old collection is heap too full.

If the old collections are triggered frequently due to failed object allocation, the gctrigger is too low. Increase the gctrigger by using the -XXgcTrigger option or decrease the load on the application.

3.2.3 Long Young-Collection Pause Times

Monitor the pause times for young collections by using the output of the -Xverbose:gcpause option or through Flight Recorder recordings.

If the young-collection pause times are too long, decrease the nursery size by using the -Xns option; alternatively, run a single-generational garbage collector.

3.2.4 Long Pauses in Deterministic Mode

Monitor the garbage-collection pause times in a Flight Recorder recording. Check the pause parts for pause times that are too long. If the pause parts for Compaction are too long, decrease the pause target. If the pause parts in Mark:Final, especially the ones concerning RefrenceQueues, are too long, the problem might be due to numerous java.lang.ref.Reference objects in the application. Redesign the Java application using fewer reference objects. You could also try decreasing the heap size; this causes reference objects to be handled more frequently, but reduces the number of reference objects to handle at each old collection.

3.3 Contact Oracle Support

If the solutions provided in this section do not help you solve the performance degradation problem, contact Oracle Support, as described in Chapter 9, "Contacting Oracle for Support."