Pick up
performance with generational garbage
collection
Tutorial Details:
Pick up performance with generational garbage collection
Pick up performance with generational garbage collection
By: By Ken Gottry
Use the appropriate Java HotSpot VM 1.3.1 parameters to improve throughput
arbage collection (GC) reclaims the heap space previously allocated to objects no longer needed. The process of locating and removing those dead objects can stall your Java application while consuming as much as 25 percent of throughput.
Sun Microsystems introduced generational GC in the Java HotSpot VM for Solaris. Generational GC separates older and newer objects into separate heap spaces. With command line parameters, you control how the HotSpot JVM uses that heap space to perform GC. HotSpot's default parameters are effective for most small applications that require faster startup and a smaller footprint. But you can select parameters that activate the Java HotSpot Server VM to improve the throughput of large, server-side applications, like those running under BEA's WebLogic, by 20 percent or more.
This article is written from the perspective of the infrastructure architect, not the Java developer. I don't explain how to modify Java code to achieve better GC. Instead, I show how the HotSpot JVM uses the system resources allocated to it to provide significant throughput improvement with no code modifications.
Pre-HotSpot JVMs
Prior to HotSpot, most JVMs had three main GC problems. First, all objects were scanned during every GC. As the number of objects increased, this type of GC's performance time increased as well.
Second, partially accurate GC algorithms were conservative when reclaiming memory. These algorithms had difficulty differentiating between pointers and other data types. This often meant the algorithm would fail to collect all garbage for fear of eliminating valid data objects.
Third, a garbage collector used handles to refer indirectly to objects in memory. Those handles were thought to expedite and simplify object relocation during garbage collection; however, they proved to be a significant performance bottleneck. The inability to relocate objects caused significant memory fragmentation and prevented the use of more sophisticated GC algorithms. Other collectors used handleless objects, but when relocated objects were collected, all other objects had to be scanned so that pointers to relocated objects could be updated.
Post-HotSpot JVM
The Exact VM (JVM 1.2.2) introduced exact garbage collection. Sun then improved the exact GC design in JVM 1.3 and renamed it generational GC. Java HotSpot VM 1.3.1's GC is fully accurate, guaranteeing that:
You can reliably reclaim all inaccessible objects' memory
You can relocate all objects to compact memory, eliminating object memory fragmentation
The HotSpot JVM uses a two-machine-word object header, rather than the three-word header found in most other JVMs. This saves as much as 10 percent of the heap size for typical applications while accelerating the code to scan all objects.
The HotSpot JVM also eliminates the concept of handles. This reduces memory usage and speeds processing. In the HotSpot JVM, object references are implemented as direct pointers, providing C-speed access to instance variables.
Three types of collection algorithms
The HotSpot JVM provides three GC algorithms, each tuned for a specific type of collection within a specific generation. The copy (also known as scavenge ) collection quickly cleans up short-lived objects in the new generation heap. The mark-compact algorithm employs a slower, more robust technique to collect longer-lived objects in the old generation heap. The incremental algorithm attempts to improve old generation collection by performing robust GC while minimizing pauses.
Copy/scavenge collection
Using the copy algorithm, the JVM reclaims most objects in the new generation object space (also known as eden ) simply by making small scavenges -- a Java term for collecting and removing refuse. Longer-lived objects are ultimately copied, or tenured, into the old object space.
Mark-compact collection
As more objects become tenured, the old object space begins to reach maximum occupancy. The mark-compact algorithm, used to collect objects in the old object space, has different requirements than the copy collection algorithm used in the new object space.
The mark-compact algorithm first scans all objects, marking all reachable objects. It then compacts all remaining gaps of dead objects. The mark-compact algorithm occupies more time than the copy collection algorithm; however, it requires less memory and eliminates memory fragmentation.
Incremental (train) collection
The new generation copy/scavenge and the old generation mark-compact algorithms can't eliminate all JVM pauses. Such pauses are proportional to the number of live objects. To address the need for pauseless GC, the HotSpot JVM also offers incremental, or train, collection.
Incremental collection breaks up old object collection pauses into many tiny pauses even with large object areas. Instead of just a new and an old generation, this algorithm has a middle generation comprising many small spaces. There is some overhead associated with incremental collection; you might see as much as a 10-percent speed degradation.
The -Xincgc and -Xnoincgc parameters control how you use incremental collection. The next release of HotSpot JVM, version 1.4, will attempt continuous, pauseless GC that will probably be a variation of the incremental algorithm. I won't discuss incremental collection since it will soon change.
Performance factors
JVM performance is usually measured by its GC's effectiveness. "Tuning Garbage Collection with the 1.3.1 Java Virtual Machine" covers performance considerations in more depth. I will cover those factors that concern this article.
A JVM's throughput accounts for the percentage of total time GC does not take place. Therefore, 80 percent throughput implies that garbage collection consumes 20 percent of the JVM's processing while your application consumes only 80 percent. Throughput is also measured in pauses, during which your application stops processing while the JVM collects garbage.
Footprint accounts for the JVM's required amount of memory. On computers with limited memory, a large footprint can increase swapping and paging , where the operating system (OS) struggles to find free memory pages for the JVM to use. As OS paging increases, it consumes more processors and likely decreases the JVM's overall performance.
Command line parameters that divide the heap between new and old generations usually cause the greatest performance impact. If you increase the new generation's size, you often improve the overall throughput; however, you also increase footprint, which may slow down servers with limited memory.
Heap layout
The HotSpot JVM manages heap space in generations -- that is, memory pools for both new and old objects. As these objects accumulate, eventually a low memory condition occurs, forcing garbage collection to take place. Figure 1 illustrates the heap space divided into the old and the new generation.
Figure 1. Heap broken into its components
The new generation includes the new object space (eden), plus two survivor spaces (SS#1 and SS#2), as Figure 1 shows. New objects allocate in eden. Longer-lived objects are moved from the new generation and tenured to the old generation.
Figure 1 shows another heap section, called the permanent generation , which holds the JVM's class and method objects. The -XX:MaxPermSize=64m command line parameter controls the permanent generation's size. I won't discuss the permanent generation further in this article.
Control the heap size
You can control the heap size using several parameters. The -Xms and -Xmx parameters define the minimum and maximum heap sizes, respectively. Most large, server-side applications set the values equal to each other for a fixed heap size.
If you set those parameters unequal, then the JVM must increase or decrease the heap size at each collection; the objective is to keep the living object space's proportion within a specific range. The -Xminf and -Xmaxf parameters define the total heap size's minimum proportion and the maximum proportion, respectively.
If you use expandable heaps, you should bear in mind the impact of changing the old and new generation heap sizes. When the heap grows or shrinks, the JVM must recalculate the old and new generation sizes in order to maintain a predefined ratio (the NewRatio parameter).
The NewSize and MaxNewSize parameters control the new generation's minimum and maximum size, respectively. You can regulate the new generation size by setting these parameters equal. You can gain a fine granularity when using these parameters to tune the new generation.
Garbage collections
When the new generation fills up, it triggers a minor collection, in which 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.
Minor collections
The Java HotSpot VM 1.3.1 uses copying collection for all minor collections. Figure 2's top portion shows that newly allocated objects (the blank circles) exist in eden. During a minor collection, the living objects (the dark circles) in eden are copied to the first survivor space. Once the copy is complete, you can use the entire eden space.
Figure 2. Minor collections. Click on thumbnail to view full-size image.
During the next GC, the living objects from eden and from the first survivor space are copied to the second survivor space. This is illustrated in Figure 2's middle portion, where all the living objects are copied, thus leaving only newly allocated objects in eden and the first survivor space.
The minor collection copies objects between survivor spaces until they become tenured; those objects are then copied to the old generation, as Figure 2's bottom portion shows.
Ma
Read
Tutorial at: Click here to view the tutorial
Rate Tutorial: Pick up
performance with generational garbage
collection
View Tutorial: Pick up
performance with generational garbage
collection
Related
Tutorials:
|