Java Performance Tuning
Java(TM) - see bottom of page
Our valued sponsors who help make this site possible
JProfiler: Get rid of your performance problems and memory leaks!
Training online: Concurrency, Threading, GC, Advanced Java and more ...
Question of the month: 1.4.1 Garbage collection algorithms, January 29th, 2003
JProfiler
|
Get rid of your performance problems and memory leaks!
|
JProfiler
|
Get rid of your performance problems and memory leaks!
|
|
|
Back to newsletter 026 contents
What is the difference between the various garbage collectors in 1.4.1?
The 1.4.1 SDK was released with at least six different garbage collection algorithms. To understand the differences between these algorithms, you first need to understand that in 1.4.1 (and previous JVMs since one of the 1.2 releases) the JVM heap is divided into two main areas: the young generation and the old generation. First, a digression on why there are these two areas of heap. (Note that the following explanations are simplified, avoiding complexities such as that the heap has more areas like Perm space, and that objects too large for the young generation are created in the old generation.)
Analysis of object lifecycles in many object-oriented programs shows that most objects tend to have very short lifetimes, with fewer objects having intermediate length lives and some objects being very long-lived. Garbage collection of short-lived objects can be achieved efficiently using a copying collector, whereas a mark-and-sweep collector is more useful for the full heap because this collector avoids object leaks. In their most basic terms, a copying collector copies all live objects from area1 to area2, which then leaves area1 free to reuse for new objects or the next copy collection. A mark-and-sweep collector finds all objects that can be reached from the JVM roots by traversing all object nodes (instance variables and array elements), marking all reached objects as "alive", then sweeping away all remaining objects (the dead objects). Copy collection time is roughly proportional to the number of live objects, mark-and-sweep collection is roughly proportional to the size of the heap.
So the heap is split into the young generation and the old generation so that a copying collection algorithm can be used in the young generation and a mark-and-sweep collection algorithm can be used in the old generation. Objects are created in the young generation, most live and die in that heap space and are efficiently collected without forcing a full mark-and-sweep collection. Some objects get moved over to the old generation because they live too long, and if the old generation gets full enough, a mark-and-sweep collection must run.
Okay, now you are armed with sufficient knowledge to understand the six 1.4.1 garbage collectors that I know about. There are three available for the young generation, and three for the old generation. Collectors labelled "parallel" use multiple threads to parallelize the collection and hence shorten the time taken on multiple-CPU machines. Collectors labelled "concurrent" allow application processing to proceed concurrently while the collection is executing, thus reducing or eliminating pauses in the application caused by garbage collection.
Young generation garbage collection algorithms
- The (original) copying collector (Enabled by default). When this collector kicks in, all application threads are stopped, and the copying collection proceeds using one thread (which means only one CPU even if on a multi-CPU machine). This is known as a stop-the-world collection, because basically the JVM pauses everything else until the collection is completed.
- The parallel copying collector (Enabled using -XX:+UseParNewGC). Like the original copying collector, this is a stop-the-world collector. However this collector parallelizes the copying collection over multiple threads, which is more efficient than the original single-thread copying collector for multi-CPU machines (though not for single-CPU machines). This algorithm potentially speeds up young generation collection by a factor equal to the number of CPUs available, when compared to the original singly-threaded copying collector.
- The parallel scavenge collector (Enabled using -XX:UseParallelGC). This is like the previous parallel copying collector, but the algorithm is tuned for gigabyte heaps (over 10GB) on multi-CPU machines. This collection algorithm is designed to maximize throughput while minimizing pauses. It has an optional adaptive tuning policy which will automatically resize heap spaces. If you use this collector, you can only use the the original mark-sweep collector in the old generation (i.e. the newer old generation concurrent collector cannot work with this young generation collector).
Old generation garbage collection algorithms
- The (original) mark-sweep collector (Enabled by default). This uses a stop-the-world mark-and-sweep collection algorithm. The collector is single-threaded, the entire JVM is paused and the collector uses only one CPU until completed.
- The concurrent collector (Enabled using -XX:+UseConcMarkSweepGC). This collector tries to allow application processing to continue as much as possible during the collection. Splitting the collection into six phases described shortly, four are concurrent while two are stop-the-world:
1. the initial-mark phase (stop-the-world, snapshot the old generation so that we can run most of the rest of the collection concurrent to the application threads);
2. the mark phase (concurrent, mark the live objects traversing the object graph from the roots);
3. the pre-cleaning phase (concurrent);
4. the re-mark phase (stop-the-world, another snapshot to capture any changes to live objects since the collection started);
5. the sweep phase (concurrent, recycles memory by clearing unreferenced objects);
6. the reset phase (concurrent).
If "the rate of creation" of objects is too high, and the concurrent collector is not able to keep up with the concurrent collection, it falls back to the traditional mark-sweep collector.
- The incremental collector (Enabled using -Xincgc). The incremental collector uses a "train" algorithm to collect small portions of the old generation at a time. This collector has higher overheads than the mark-sweep collector, but because small numbers of objects are collected each time, the (stop-the-world) garbage collection pause is minimized at the cost of total garbage collection taking longer. The "train" algorithm does not guarantee a maximum pause time, but pause times are typically less than ten milliseconds.
The JavaPerformanceTuning.com team
Back to newsletter 026 contents
Last Updated: 2024-11-29
Copyright © 2000-2024 Fasterj.com. All Rights Reserved.
All trademarks and registered trademarks appearing on JavaPerformanceTuning.com are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries. JavaPerformanceTuning.com is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
URL: http://www.JavaPerformanceTuning.com/news/qotm026.shtml
RSS Feed: http://www.JavaPerformanceTuning.com/newsletters.rss
Trouble with this page? Please contact us