UNPKG

epubjs

Version:

Render ePub documents in the browser, across many devices

125 lines (124 loc) 12.8 kB
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <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>