this simple loop is executed for a year's worth of stock prices (roughly 250 iterations), 750
BigDecimal objects are created to store the intermediate values just in this loop. Those ob-
jects are discarded on the next iteration of the loop. Within the add() and other methods, the
JDK library code creates even more intermediate BigDecimal (and other) objects. In the end,
a lot of objects are created and discarded very quickly in this very small amount of code.
This kind of operation is quite common in Java and so the garbage collector is designed to
take advantage of the fact that many (and sometimes most) objects are only used temporarily.
This is where the generational design comes in. Objects are first allocated in the young gen-
eration, which is some subset of the entire heap. When the young generation fills up, the
garbage collector will stop all the application threads and empty out the young generation.
Objects that are no longer in use are discarded, and objects that are still in use are moved
elsewhere. This operation is called a minor GC.
There are two performance advantages to this design. First, because the young generation is
only a portion of the entire heap, processing it is faster than processing the entire heap. This
means that the application threads are stopped for a much shorter period of time than if the
entire heap were processed at once. You probably see a trade-off there, since it also means
that the application threads are stopped more frequently than they would be if the JVM
waited to perform GC until the entire heap were full; that trade-off will be explored in more
detail later in this chapter. For now, though, it is almost always a big advantage to have the
shorter pauses even though they will be more frequent.
The second advantage arises from the way objects are allocated in the young generation. Ob-
jects are allocated in eden (which comprises the vast majority of the young generation).
When the young generation is cleared during a collection, all objects in eden are either
moved or discarded: all live objects are moved either to one of the survivor spaces or to the
old generation. Since all objects are moved, the young generation is automatically compacted
when it is collected.
All GC algorithms have stop-the-world pauses during collection of the young generation.
As objects are moved to the old generation, eventually it too will fill up, and the JVM will
need to find any objects within the old generation that are no longer in use and discard them.
This is where GC algorithms have their biggest differences. The simpler algorithms stop all
application threads, find the unused objects and free their memory, and then compact the
heap. This process is called a full GC, and it generally causes a long pause for the application
On the other hand, it is possible—though more computationally complex—to find unused
objects while application threads are running; CMS and G1 both take that approach. Because