bea.com | products | dev2dev | support | askBEA
 Download Docs   Site Map   Glossary 
Search

JRockit for Windows and Linux User Guide

 Previous Next Contents View as PDF  

Configuring the JRockit Memory Management System

Have you ever seen strange pauses in your application that you haven't been able to explain? Have you seen one or all CPUs pegged on 100% utilization and all the others on 0% and still very few transactions in your system? If you answered yes to either of these two questions, your application might have been suffering from the effects of a poorly performing garbage collector. Some fairly simple tuning of the memory management system can improve performance dramatically for many applications.

This section includes information on the following subjects:

 


Memory Management Terminology

Before continuing, there are some terms you should understand. You may already be familiar with some of the terms, especially if you have read any other documents about garbage collectors.

Thread-local allocation

Thread-local allocation is not the same thing as thread-local objects, but many people tend to confuse the two terms. Thread-local allocation does not determine whether the objects can be accessed from a single thread only (that is, thread-local objects); thread-local allocation means that the thread has an area of its own where no other thread will create new objects. The objects that the thread creates in that area may still be reached from other threads. Thread-local allocation removes object allocation contention and reduces the need to synchronize between thread performing allocations on the heap. It also gives increased cache performance on a multi-CPU system, because it reduces the risk of two threads running on different CPUs having to access the same memory pages at the same time.

Pause time

Garbage collector pause time is the length of time that the garbage collector stops all Java threads during a garbage collection. The longer the pause, the more unresponsive your system will be. The worst pause time and the average pause time are the two most interesting values you can use for tuning the system.

Memory throughput

Memory throughput measures the time it takes between when an object is no longer referenced and the time it gets reclaimed and returned as free memory. The higher the memory throughput the shorter is the time between the two events. Moreover, the higher the memory throughput the smaller the heap you will need.

 


JRockit Garbage Collectors

This section describes the garbage collectors available in JRockit. These collectors are:

Generational Copying Garbage Collectors

The first type of JRockit garbage collector is the generational copying garbage collector (-Xgc:gencopy).

A generational garbage collector divides the memory into two or more areas called "generations". Instead of allocating objects in one single space and garbage collecting that whole space when it gets full, most of the objects are allocated in the "young generation", called the nursery. As most objects die young, most of the time it will be sufficient to garbage collect only the nursery and not the entire heap.

A generational copying garbage collector is specifically designed as a lightweight alternative for use on single CPU systems with a small (less then 128 mB) heap. It is suitable for testing applications on your desktop machine; however for a deployment environment another garbage collector would in most cases be more efficient.

Concurrent Garbage Collectors

A concurrent garbage collector does its work in parallel with ordinary work; that is, it does not stop all Java threads to do the complete garbage collection. Most garbage collectors today are "stop-the-world," or parallel, collectors and are not very efficient. Using a parallel collector, if you have to garbage collect the whole of a large heap, there could be a pause of up to several seconds, depending on the heap size. Concurrent garbage collectors are designed to rectify this condition.

JRockit can employ two types of concurrent garbage collectors:

Single Spaced Concurrent

The second type of JRockit garbage collector is the single spaced concurrent garbage collector (-Xgc:singlecon). What is unique about the concurrent garbage collectors is that they remove garbage collection pauses completely. Using these garbage collectors, the heaps can be gigabyte-size and there will be no long pauses. However, keep in mind that concurrent garbage collectors trade memory throughput for reduced pause time. It takes longer between the time the object is referenced the last time and the system detects and reclaims it; in other words it takes longer for the object to die. The natural consequence of this is that you will most likely need a larger heap with a concurrent garbage collector than you need with any other. In addition, if your ordinary Java threads create more garbage than the concurrent garbage collector manages to collect, there will be pauses while the Java threads are waiting for the concurrent garbage collector to complete its cycle.

Generational Concurrent

The third type of JRockit garbage collector is the generational concurrent garbage collector (-Xgc:gencon). In this garbage collector, objects are allocated in the young generation. When the young generation (called a nursery) is full, JRockit "stops-the-world" and moves the objects that are still live in the young generation to the old generation. An old collector thread runs in the background all the time; it marks objects in the old space as live and removes the dead objects, returning them to JRockit as free space.

The advantage of the generational concurrent garbage collector compared to the single spaced concurrent garbage collector is that it has a higher memory throughput.

Parallel Garbage Collectors

The fourth type of JRockit garbage collector is the parallel garbage collector (-Xgc:parallel). When the heap is full all Java threads are stopped and every CPU is used to perform a complete garbage collection of the entire heap. This behavior causes longer pause times than for the concurrent collectors but maximizes memory throughput. On a machine with four CPUs or better this is the recommended garbage collector, provided that your application can tolerate the slightly longer pause times.

 


Choosing a Garbage Collection Method

Each of the four garbage collectors has its benefits and its drawbacks. In an effort to help you choose the collector that best suits your needs, this section discusses the pros and con of each collector and provides a matrix to help you decide which one to use.

Pros and Cons

Table 6-1 lists the pros and cons of each garbage collector.

Table 6-1 Garbage Collector Pros and Cons

Garbage Collector

Pros

Cons

Generational Copying

  • Works well with single CPU systems with a heap smaller than 128mB.

  • Good for testing on a single machine.

  • Not effective with large (>128mB) heaps.

  • Not recommended in a deployment environment.

Single Spaced Concurrent

  • Virtually removes all pauses.

  • Can handle gigabyte-sized heaps.

  • Trades memory for fewer pauses.

  • If ordinary Java threads create more garbage than this collector can collect, pauses occur while these threads are waiting for the collector to complete its cycle.

Generational Concurrent

  • Virtually removes all pauses.

  • Has a higher memory throughput than single spaced concurrent garbage collector

  • Trades memory for fewer pauses.

  • If ordinary Java threads create more garbage than this collector can collect, pauses occur while these threads are waiting for the collector to complete its cycle.

Parallel

  • Maximizes memory throughput.

  • "Stop the world" might cause a longer than desirable pause in processing.

Garbage Collector Selection Matrix

Table 6-2 is a matrix that you can use to determine which garbage collector is right for your JRockit implementation. Use the If... column to locate a condition that matches your JRockit implementation and select the garbage collector indicated in the Select this Method... column.

Table 6-2 Garbage Collector Selection Matrix

If You...

Select this Garbage Collector...

  • Want lightweight alternative for use on single CPU systems with a small (less then 128 mB) heap.

  • Are testing applications on your desktop machine.

Generational Copying

  • Cannot tolerate pauses of any length.

  • Employ gigabyte-sized heaps.

  • Willing to trade memory thoughput for eliminating pauses.

Single Spaced Concurrent

  • Cannot tolerate pauses of any length.

  • Employ gigabyte-sized heaps.

  • Willing to trade some memory thoughput for eliminating pauses.

  • Want better memory throughput than possible with Single Spaced Concurrent

Generational Concurrent

  • Using a machine with four CPUs or better.

  • Can tolerate the occasional long pause

  • Need to maximize memory throughput

Parallel

 


Implementing a Garbage Collector

To implement a garbage collector, simply enter at the command line the option for the desired collector. Table 6-3 lists these options:

Table 6-3 Garbage Collector Implementation Options

Garbage Collector

Option

Generational Copying

-Xgc:gencopy

Single Spaced Concurrent

-Xgc:singlecon

Generational Concurrent

-Xgc:gencon

Parallel

-Xgc:parallel

When started, JRockit will run with the specified garbage collector.

 


Configuring the Garbage Collector

To provide the optimal out-of-the-box experience with JRockit comes with default values that adapt automatically to the specific platform on which you are running JRockit (see System Defaults" on page 9). You can modify these values to tune your garbage collector by specifying at the command line any of the options listed in this section.

Warning: -X options are non-standard and are subject to change at any time.

Printing a Comprehensive Report

-Xgcreport

-Xgcreport causes JRockit to print a comprehensive garbage collection report at program completion. The option -Xgcpause causes JRockit to print a line each time Java threads are stopped for garbage collection. Combining the two is a very good way of examining the memory behavior of your application.

Setting the Initial and Maximum Heap Size

-Xmx:<size>/-Xms<size>

-Xmx sets the maximum size of the heap. The general recommendation is to set this as high as possible, but not so high that it causes page-faults for the application or for some other application on the same computer. Set it to something less than the amount of memory in the machine. If you have multiple applications running on the computer at the same time the value could be much lower. The general recommendation is to set the initial heap size (-Xms) to the same size as the maximum heap size.

Setting the Size of the Nursery

-Xns:<size>

-Xns sets the size of the young generation (nursery) in generational concurrent and generational copying garbage collectors (these are the only collectors that use nurseries). If you are creating a lot of temporary objects you should have a large nursery. Generally, the larger you can make the nursery while keeping the GC-pause times acceptably low, the better. You can see the nursery pause times in JRockit by starting the JVM with -Xgcpause, but you have to decide yourself what is an acceptable garbage collection pause time before your system becomes unresponsive.

Setting the Type of Thread Allocation

-Xallocationtype:<global|local>

-Xallocationtype sets the type of thread allocation. The allocation type local is recommended for the vast majority of applications. However, if the maximum heap size is very small (less then 128 MB) or if the number of threads used by the application is very high (several hundred) the allocation type global might work better, particularly on single CPU systems. The reason for this is that every thread-local area consumes a fixed amount of memory (approximately 2 kilobytes). If the number of threads is very high or the heap size very small when using thread-local allocation the potential waste of space could cause excess fragmentation of the heap. This leads to more frequent garbage collections and may cause the application to run out of memory prematurely.

Defining When a Memory Space will be Cleared

-Xcleartype:<gc|local|alloc>

-Xcleartype defines when the memory space occupied by an object that has been garbage collected will be cleared. It can be done during the garbage collection (gc), when a thread-local area is allocated (local) or when that space is allocated for a new object (alloc). You should use local or alloc. alloc might work better if the objects allocated are very large (1 to 2 kilobytes).

Note these additional conditions:

Printing the Pause Times

-Xgcpause

-Xgcpause prints pause times caused by the garbage collector.

 


System Defaults

This section describes the default values for the JRockit memory management system. To provide the best out-of-the-box performance possible these defaults adapt automatically to the specific platform on which JRockit is running.

Heap Size

If the initial heap size (-Xms) is not set, the default initial heap size depends on the maximum heap size (-Xmx) value and on the amount of available physical memory. If the maximum heap size or the available physical memory is less than 128 MB the initial heap size will be 16 MB. If the maximum heap size is larger than 128 MB the initial heap size will be 75% of the available physical memory up to 64 MB.

Garbage Collector

If the garbage collector (-Xgc) has not been set and the maximum heap size (set by using -Xmx or using the default as described above) is less than 128 MB, the default garbage collector is generational copying (gencopy); otherwise the default is generational concurrent (gencon).

Nursery Size

If the nursery size (-Xns) has not been set the default size depends on the number of CPUs. For the generational copying (gencopy) garbage collector the default nursery size is 640 KB times the number of CPUs and for the generational concurrent (gencon) garbage collector the default nursery size is 10 MB times the number of CPUs.

Thread Stack Size

If the thread stack size (-Xss) has not been set the default value depends on the threading system and the platform you are running on. When using thin threads the minimum thread stack size is 8 kilobytes and the default is 64 kilobytes. When using native threads the minimum thread stack size is 16 kilobytes. For Windows the default thread stack size when using native threads is 64 kilobytes and for Linux it is 128 kilobytes.

Note: If -Xss is set below the minimum value, thread stack size will default to the minimum value automatically.

Allocation Type

If the allocation type (-Xallocationtype) is not set, the default is global for the generational copying (gencopy) garbage collector and local for all others (singlecon, gencon, and parallel).

Clear Type

If the clear type (-Xcleartype) is not set the default is alloc on IA32 systems and gc on IA64 systems.

Note: The option alloc is not available on IA64 systems.

 

Back to Top Previous Next