Java 7 for Absolute Beginners

(nextflipdebug5) #1

CHAPTER 13 ■ GARBAGE COLLECTION


real-time monitoring of things like valves in a refinery. Later versions fixed that problem, but the
reputation lingered for several more versions (and still pops up in some circles).
So how does one collect objects and still let the program run? In particular, how does one allow
creation of new objects and send existing objects to collection while letting the garbage collector run?
Two more advanced algorithms have been developed: Incremental garbage collection and concurrent
garbage collection.
Incremental garbage collection relies on intermittently stopping and starting both the program and
the garbage collector (which is really just another program being run in parallel by the JVM). Essentially,
the program gets to do a bit of work, and then the garbage collector gets to do a bit, and so on. In this
fashion, the program gets to do some work while the garbage collector runs. As you can imagine, though,
the program's performance is still slower than when the garbage collector is not running. In fact,
versions of Java had noticeably slower performance when the garbage collector ran. I recall playing a
video game written in Java and being able to tell when the garbage collector started and stopped.
Concurrent garbage collection lets the program run at full speed, with one exception: The program
must be halted while the stack (the list of objects in memory) is scanned. Fortunately, scanning the stack
takes very little time. Scanning the stack (which is really just a list) takes much less time than does
scanning the heap (which is all of the objects in memory). Imagine reading a book's table of contents
versus reading the whole book, and you'll have an idea of the difference.
So how does a concurrent garbage collector let the program run at (almost) full speed? The garbage
collector doesn't concern itself with finding everything that can be collected. Instead, it finds what it can
be sure of and frees those objects. On its next pass, it can catch anything it missed, as well as anything
that has become removable in the meantime. Thus, the concurrent garbage collection rarely gets a
perfect sweep, but it lets the program run much more smoothly.
Java 1.4.2 (which was a “red letter” release in the Java community, partly because of garbage
collection) introduced a garbage collector that can be switched between incremental garbage collection
and concurrent garbage collection. (It actually supports 4 kinds of garbage collection: two variants of
naïve garbage collection, incremental garbage collection, and concurrent garbage collection.) Software
developers could then decide (preferably through testing) which kind of collection worked best for their
programs. Suddenly, the performance of many Java programs got a big boost. At that point, Java could
finally compete with non-garbage-collecting languages (notably C++) in the arena of high performance
applications. Java 5 (also known as Java 1.5) and Java 6 (or Java 1.6) continued to add fine tuning to the
garbage collector, through various switches that could be set on the collector. We'll cover the most
helpful of these switches near the end of this chapter.
Enter Java 7. Java 7 provides a new collector, called G1 (for “garbage first”). The G1 collector offers a
step up from the previous garbage collectors by dividing the heap into regions (or sectors) and then
garbage collecting each sector beginning with the sector that has the most the most garbage to collect.
As a result of this “garbage-first” collection scheme, the G1 collector ensures that it gets as much garbage
as possible on any given sweep. If the G1 collector was unable to sweep the whole thing because the
program needed to run, at least it got to the worst sectors while it had a chance. Over subsequent
sweeps, the other regions gradually fill up and come to contain the most garbage. Those sectors then get
swept in their turn. Thus, the collector eventually gets to all regions in memory but doesn't try to get
them all at once. It's a nice bit of optimization that is made all the better by not needing any new settings
to control it. It's just how the G1 collector works. Also, there's no need to enable the G1 collector. If
you're using Java 7, you're using the G1 collector, unless you specify an older collector.

Understanding Memory Settings


Some programs must keep large numbers of objects in memory to work correctly. In those cases, the
only way to make them work is to expand the amount of memory available to the programs.
Free download pdf