An environment that includes garbage collection also needs to be able to move memory ob-
jects when needed. Otherwise, the memory that is being used can become fragmented (as
garbage is collected), and there are lots of optimizations that require that objects be moved.
For example, generational garbage collectors depend on the observation that most objects are
short-lived. They are allocated, used briefly, and then never used again. This means that if an
object is used for some extended period of time, it is much less likely to become garbage in the
near future. So generational collectors keep two heaps of objects. One of those heaps contains
new objects, which are likely to be collected the next time the garbage collector is run. The
other heap contains objects that have existed for some period of time (often those that have
survived a first garbage-collection sweep). When an object is determined to be long-lived, it
is moved from the new-object heap to the old-object heap. This older heap does not need to
be collected nearly as regularly as the new heap, meaning that less time needs to be spent on
garbage collection in general.
But if objects are going to be moved around, you need to make sure that those objects can still
be found and used by anyone who wants to access the object. This requires that the objects
be referenced only indirectly, and that the program cannot look into the reference (since the
program might see information that, after a garbage collection and a move, would be invalid).
It also means that if we were able to add or subtract some value to a reference and get another
reference, there is no assurance that the next time we did that same operation we would get a
reference to the same object (or to anything, for that matter).
For both of these reasons (and probably others), Java has references rather than pointers. This
is a good thing, freeing up the programmer from thinking about memory management and
allowing the system to globally manage the memory in a program. Because of garbage collec-
tion, it is not only easier to write programs in Java, but it is more likely that your program is
not subject to memory leaks and is more secure. All good things to get, especially if it doesn't
require you to think about it.
Because the Java platform has garbage collection, you might think that there is no way that
you can get into the kinds of memory management problems that are the bane of the C or C++
programmer's existence. In some cases, this is true; you won't find yourself using the same
piece of memory for two different objects in Java, or writing to a memory location that hasn't
been allocated (although you can get into trouble trying to dereference a null pointer). But
programmers are very clever people, so there are still ways to leak memory, even if the com-
puter is cleaning up after you.