epubjs
Version:
Render ePub documents in the browser, across many devices
125 lines (124 loc) • 12.8 kB
HTML
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Object Destruction</title><link rel="stylesheet" href="core.css" type="text/css"/><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"/></head><body><div class="sect1" title="Object Destruction"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-CHP-5-SECT-4"/>Object Destruction</h1></div></div></div><p>Now that we’ve seen how to create objects, it’s time to talk about
their destruction. If you’re accustomed to programming in C or C++, you’ve
probably spent time hunting down memory leaks in your code. Java takes
care of object destruction for you; you don’t have to worry about
traditional memory leaks, and you can concentrate on more important
programming tasks.<sup>[<a id="learnjava3-CHP-5-FNOTE-3" href="#ftn.learnjava3-CHP-5-FNOTE-3" class="footnote">14</a>]</sup></p><div class="sect2" title="Garbage Collection"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-5-SECT-4.1"/>Garbage Collection</h2></div></div></div><p><a id="idx10225" class="indexterm"/> <a id="idx10228" class="indexterm"/> <a id="idx10242" class="indexterm"/>Java uses a technique known as <span class="emphasis"><em>garbage
collection</em></span> to remove objects that are no longer needed. The
garbage collector is Java’s grim reaper. It lingers in the background,
stalking objects and awaiting their demise. It finds and watches them,
periodically counting references to them to see when their time has
come. When all references to an object are gone and it’s no longer
accessible, the garbage-collection mechanism declares the object
<a id="I_indexterm5_id692939" class="indexterm"/><span class="emphasis"><em>unreachable</em></span> and reclaims its space
back to the available pool of resources. An unreachable object is one
that can no longer be found through any combination of “live” references
in the running application.</p><p>Garbage collection uses a variety of algorithms; the Java virtual
machine architecture doesn’t require a particular scheme. It’s worth
noting, however, how some implementations of Java have accomplished this
task. In the beginning, Java used a technique called “mark and sweep.”
In this scheme, Java first walks through the tree of all accessible
object references and marks them as alive. Java then scans the heap,
looking for identifiable objects that aren’t marked. In this technique,
Java is able to find objects on the heap because they are stored in a
characteristic way and have a particular signature of bits in their
handles unlikely to be reproduced naturally. This kind of algorithm
doesn’t become confused by the problem of cyclic references, in which
objects can mutually reference each other and appear alive even when
they are dead (Java handles this problem automatically). This scheme
wasn’t the fastest method, however, and caused pauses in the program.
Since then, implementations have become much more sophisticated.</p><p>Modern Java garbage collectors effectively run continuously
without forcing any lengthy delay in execution of the Java application.
Because they are part of a runtime system, they can also accomplish some
things that could not be done statically. Sun’s Java implementation
divides the memory heap into several areas for objects with different
estimated lifespans. Short-lived objects are placed on a special part of
the heap, which reduces the time to recycle them drastically. Objects
that live longer can be moved to other, less volatile parts of the heap.
In recent implementations, the garbage collector can even “tune” itself
by adjusting the size of parts of the heap based on the actual
application performance. The improvement in Java’s garbage collection
since the early releases has been remarkable and is one of the reasons
that Java is now roughly equivalent in speed to traditional compiled
languages.</p><p>In general, you do not have to concern yourself with the
garbage-collection process. But one garbage-collection method can be
useful for debugging. You can prompt the garbage collector to make a
clean sweep explicitly by invoking the <a id="I_indexterm5_id692993" class="indexterm"/><code class="literal">System.gc()</code> method.
This method is completely implementation-dependent and may do nothing,
but it can be used if you want some guarantee that Java has cleaned up
before you do an activity.<a id="I_indexterm5_id693005" class="indexterm"/><a id="I_indexterm5_id693012" class="indexterm"/><a id="I_indexterm5_id693020" class="indexterm"/></p></div><div class="sect2" title="Finalization"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-5-SECT-4.2"/>Finalization</h2></div></div></div><p><a id="I_indexterm5_id693033" class="indexterm"/> <a id="I_indexterm5_id693042" class="indexterm"/> <a id="I_indexterm5_id693053" class="indexterm"/>Before an object is removed by garbage collection, its
<a id="I_indexterm5_id693064" class="indexterm"/><code class="literal">finalize()</code> method is
invoked to give it a last opportunity to clean up its act and free other
kinds of resources it may be holding. While the garbage collector can
reclaim memory resources, it may not take care of things such as closing
files and terminating network connections as gracefully or efficiently
as could your code. That’s what the <code class="literal">finalize()</code> method is for. An object’s <code class="literal">finalize()</code> method is called once and only once
before the object is garbage-collected. However, there’s no guarantee
when that will happen. Garbage collection may, in theory, never run on a
system that is not short of memory. It is also interesting to note that
finalization and collection occur in two distinct phases of the
garbage-collection process. First, items are finalized; then they are
collected. It is, therefore, possible that finalization can
(intentionally or unintentionally) create a lingering reference to the
object in question, postponing its garbage collection. The object is, of
course, subject to collection later if the reference goes away, but its
<code class="literal">finalize()</code> method isn’t called
again.</p><p>The <code class="literal">finalize()</code> methods of
superclasses are not invoked automatically for you. If you need to
invoke the finalization routine of your parent classes, you should
invoke the <code class="literal">finalize()</code> method of your
superclass, using <code class="literal">super.finalize()</code>.
We discuss inheritance and overridden methods in <a class="xref" href="ch06.html" title="Chapter 6. Relationships Among Classes">Chapter 6</a>.</p></div><div class="sect2" title="Weak and Soft References"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-5-SECT-4.3"/>Weak and Soft References</h2></div></div></div><p><a id="idx10226" class="indexterm"/> <a id="idx10243" class="indexterm"/> <a id="idx10259" class="indexterm"/> <a id="idx10263" class="indexterm"/>In general, as we’ve described, Java’s garbage collector
reclaims objects when they are unreachable. An unreachable object,
again, is one that is no longer referenced by any variables within your
application and that is not reachable through any chain of references by
any running thread. Such an object cannot be used by the application any
longer and is, therefore, a clear case where the object should be
removed.</p><p>In some situations, however, it is advantageous to have Java’s
garbage collector work with your application to decide when it is time
to remove a particular object. For these cases, Java allows you to hold
an object reference indirectly through a special wrapper object, a type
of <a id="I_indexterm5_id693199" class="indexterm"/><code class="literal">java.lang.ref.Reference</code>. If Java then decides
to remove the object, the reference the wrapper holds turns to <code class="literal">null</code> automatically. While the reference
exists, you may continue to use it in the ordinary way and, if you wish,
assign it elsewhere (using normal references), preventing its garbage
collection.</p><p>There are two types of <code class="literal">Reference</code> wrappers that implement different
schemes for deciding when to let their target references be
garbage-collected. The first is called a <a id="I_indexterm5_id693226" class="indexterm"/><code class="literal">WeakReference</code>.
<em class="firstterm">Weak references</em> are eligible for garbage
collection immediately; they do not prevent garbage collection the way
that ordinary “strong” references do. This means that if you have a
combination of strong references and references contained in <code class="literal">WeakReference</code> wrappers in your application,
the garbage collector waits until only <code class="literal">WeakReference</code>s remain and then collects the
object. This is an essential feature that allows garbage collection to
work with certain kinds of caching schemes. You’ll often want to cache
an object reference for performance (to avoid creating it or looking it
up). But unless you take specific action to remove unneeded objects from
your cache, the cache keeps those objects alive forever by maintaining
live references to them. By using weak references, you can implement a
cache that automatically throws away references when the object would
normally be garbage-collected. In fact, an implementation of <code class="literal">HashMap</code> called <code class="literal">WeakHashMap</code> is provided that does just this
(see <a class="xref" href="ch11.html" title="Chapter 11. Core Utilities">Chapter 11</a> for details).</p><p>The second type of reference wrapper is called <a id="I_indexterm5_id693282" class="indexterm"/><code class="literal">SoftReference</code>. A
<em class="firstterm">soft reference</em> is similar to a weak reference,
but it tells the garbage collector to be less aggressive about
reclaiming its contents. Soft-referenced objects are collected only when
and if Java runs short of memory. This is useful for a slightly
different kind of caching where you want to keep some content around
unless there is a need to get rid of it. For example, a web browser can
use soft references to cache images or HTML strings internally, thus
keeping them around as long as possible until memory constraints come
into play. (A more sophisticated application might also use its own
scheme based on a “least recently used” marking of some kind.)</p><p>The <a id="I_indexterm5_id693309" class="indexterm"/><code class="literal">java.lang.ref</code> package
contains the <code class="literal">WeakReference</code> and
<a id="I_indexterm5_id693326" class="indexterm"/><code class="literal">SoftReference</code> wrappers,
as well as a facility called <code class="literal">ReferenceQueue</code> that allows your application to
receive a list of references that have been collected. It’s important
that your application use the queue or some other checking mechanism to
remove the <code class="literal">Reference</code> objects
themselves after their contents have been collected; otherwise, your
cache will soon fill up with empty <code class="literal">Reference</code> object wrappers.<a id="I_indexterm5_id693358" class="indexterm"/><a id="I_indexterm5_id693365" class="indexterm"/><a id="I_indexterm5_id693372" class="indexterm"/><a id="I_indexterm5_id693379" class="indexterm"/></p></div><div class="footnotes"><br/><hr/><div class="footnote"><p><sup>[<a id="ftn.learnjava3-CHP-5-FNOTE-3" href="#learnjava3-CHP-5-FNOTE-3" class="para">14</a>] </sup>It’s still possible in Java to write code that holds onto
objects forever, consuming more and more memory. This isn’t really a
leak so much as it is hoarding memory. It is also usually much easier
to track down with the correct tools and techniques.</p></div></div></div></body></html>