http://java.sun.com/developer/technicalArticles/ALT/RefObj/








<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang='en'>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Reference Objects and Garbage Collection</title>
<meta name="collection" content="reference">
<meta http-equiv="content-language" content="en">
<meta name="keywords" content="advanced, language, topics, reference, object, reflection, garbage, collection">
<meta name="description" content="The Reference Objects API lets a program maintain a special reference to an object so it can interact with the garbage collector.">
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta name="archive" content="false">
<meta name="archive" content="FALSE">
<meta name="date" content="2003-03-22">
<link rel="stylesheet" href="/css/default_developer.css" />


<script type="text/javascript" language="JavaScript" src="/js/popUp.js"></script>
<script language="javascript1.2" type="text/javascript" src="/js/sniff.js"></script>
<script language="javascript1.2" type="text/javascript" src="/js/menucontent.js"></script>
<script language="javascript1.2" type="text/javascript" src="/js/menucode.js"></script>
<script language="javascript1.2" type="text/javascript" src="/js/developer.js"></script>


</head>
<!--stopindex-->
<body leftmargin="0" topmargin="0" marginheight="0" marginwidth="0" rightmargin="0" bgcolor="#ffffff" onload="prepmenus(); done=true">

<a name="top"></a>
<!-- BEGIN GENERIC MASTHEAD -->


<!-- BEGIN A1 COMPONENT V.0 -->
<div class="a1 a1r2">
<div class="a1v0">
<a href="#skip2content" class="skiplink">Skip to Content</a>
<span class="toolbarlinks">
<a href="/global/mh/java/">Java</a>
<a href="/global/mh/solaris/">Solaris</a>
<a href="/global/mh/communities/" class="dividelink">Communities</a>
<a href="http://developers.sun.com/global/my_profile.html">My SDN Account</a>
<a href="http://developers.sun.com/global/join_sdn.html" class="dividelink">Join SDN</a>
</span>
</div>
</div>
<!-- END A1 COMPONENT V.0 -->


<!-- BEGIN A2 COMPONENT V.1 -->
<div class="a2w0">
<div class="a2" id="a2v1">
<div class="a2w1"><div class="a2w2"><div class="a2w3"><div class="a2w4">
<div class="a2topiclinks">
<div class="a2search">
<form action="http://developers.sun.com/search/onesearch/index.jsp" accept-charset="utf-8" method="GET">
<input type="hidden" name="charset" value="utf-8"><input type="hidden" name="col" value="developer-reference">
<span class="rightarrowwhite">&raquo;</span>&nbsp;<a href="http://developers.sun.com/global/search_tips.html">search tips</a>&nbsp;
<input class="searchfield" name="qt" class="medium" size="7" onFocus="if( this.value==this.defaultValue ) this.value=;" value="Search">
<input id="searchbttn" type="image" border="0" src="/im/a2_bttn_search.gif" alt="Submit Search">
</form>
</div>
<a href="http://java.sun.com" title="Home Page" id="sunlogo"><img src="/im/a.gif" alt="Home Page" width="98" height="58" border="0" /></a>
<a href="http://developers.sun.com" title="Sun Developer Network"><img src="/im/a.gif" id="venuespacer" alt="Sun Developer Network" width="400" height="33" border="0" /></a>
<ul id="mtopics">
<li id="mtopic1"><a id="glink1" class="tpclink a2menu" title="See All APIs" href="/global/mh/api/index.html">APIs</a></li>
<li id="mtopic2"><a id="glink2" class="tpclink a2menu" title="See All Downloads" href="/global/mh/downloads/index.html">Downloads</a></li>
<li id="mtopic3"><a id="glink3" class="tpclink a2menu" title="See All Technologies &amp; Solutions" href="/global/mh/tech/index.html">Technologies</a></li>
<li id="mtopic4"><a id="glink4" class="tpclink a2menu" title="See All Products" href="/global/mh/products/index.html">Products</a></li>
<li id="mtopic5"><a id="glink5" class="tpclink a2menu" title="See All Support" href="/global/mh/support/index.html">Support</a></li>
<li id="mtopic6"><a id="glink6" class="tpclink a2menu" title="See All Training" href="/global/mh/training/index.html">Training</a></li>
<li id="mtopic7"><a id="glink7" class="tpclink a2menu" title="See All Sun.com" href="/global/mh/suncom/index.html">Sun.com</a></li>
</ul>
</div>
</div></div></div></div>
</div></div>
<!-- END A2 COMPONENT V.1 -->









<!-- END GENERIC MASTHEAD -->
<!-- BEGIN BREADCRUMB -->
<table border="0" cellpadding="0" cellspacing="0" width="100%" class="vatop">
<tr>
<td>      
<div class="breadcrumb">
<a href="http://developers.sun.com/index.html">Developers Home</a> &gt; <a href="http://developers.sun.com/prodtech/index.html">Products & Technologies</a> &gt; <a href="http://java.sun.com/index.jsp">Java Technology</a> &gt; <a href="http://java.sun.com/reference/index.html">Reference</a> &gt; <a href="http://java.sun.com/reference/techart/index.html">Technical Articles and Tips</a> &gt; <a href="http://java.sun.com/developer/technicalArticles/index.html">Developer Technical Articles & Tips</a> &gt; <a href="http://java.sun.com/developer/technicalArticles/ALT/index.html">Advanced Language Topics</a> &gt;
</div>
</td>
<td align="right" nowrap="nowrap"><div class="breadcrumb">
</div></td></tr>
<tr><td colspan="2"><img src="/im/a.gif" width="770" height="1" border="0" alt=" " /></td></tr>
</table>
<span class="sp5">&nbsp;</span><br />     
<!-- END BREADCRUMB -->
<!-- BEGIN PAGETITLE -->
<div class="pagetitle2">Article</div>
<div class="smallpagetitle"><h1>Reference Objects and Garbage Collection</h1></div>
<!-- END PAGETITLE -->
<!-- BEGIN WRAPPER TABLE, 2 COLUMN, MAIN/RIGHT -->
<table border="0" cellpadding="10" cellspacing="0" width="100%">
<tr><td width="100%" valign="top">
<!-- BEGIN CENTRAL COLUMN COMPONENTS -->
<!--startindex-->
<!-- ============ -->
<!-- MAIN CONTENT -->
<!-- ============ -->
<a name="skip2content"></a>
<!--  BEGIN VCD4 PFV  -->
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td class="smaller" valign="top"><em></em></td>
<td width="10">&nbsp;</td>
<td align="right" valign="bottom"><div class="sitelinks" style="padding:0px;">
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td valign="bottom" align="right">&nbsp;</td>
<td valign="bottom" class="smaller" nowrap="nowrap"><a href="/jsp_utils/PrintPage.jsp" target="printFriendlyView" onclick="openPopup('','printFriendlyView',710,650,'no',1,1,0,0,0,0); return true;"><img src="/im/ic_print.gif" width="14" height="12" alt="Print-friendly Version" border="0" hspace="4" />Print-friendly Version</a><br></td>
</tr></table></div>
</td></tr>
</table>
<!--  END VCD4 PFV -->
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr><td class="smaller" valign="top"><em>
By <a href="#author">Monica Pawlan</a>, August 1998
</em></td>
<td width="10">&nbsp;</td>
<td align="right" valign="bottom">
<div class="sitelinks" style="padding:0px;">
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<!--
<td valign="bottom" align="right"><img src="/im/ic_email.gif" width="14" height="12" border="0" hspace="4" vspace="1" alt=" " /></td>
<td valign="bottom" class="smaller" nowrap="nowrap"><a href="#{link placeholder}">E-mail</a></td>
<td>&nbsp;&nbsp;</td>
<td valign="bottom" align="right">&nbsp;</td>
<td valign="bottom" class="smaller" nowrap="nowrap"><a href="/jsp_utils/PrintPage.jsp" target="printFriendlyView" onclick="openPopup('','printFriendlyView',710,650,'no',1,1,0,0,0,0); return true;"><img src="/im/ic_print.gif" width="14" height="12" alt="Print-friendly Version" border="0" hspace="4" />Print-friendly Version</a></td>
<td>&nbsp;&nbsp;</td>
<td valign="bottom" align="right"><img src="/im/ic_download_thin.gif" width="9" height="14" hspace="4" border="0" alt=" " /></td>
<td valign="bottom" class="smaller" nowrap="nowrap"><a href="#{link placeholder}">Download</a></td>
-->
</tr>
</table>
</div>
</td></tr>
</table>
<div class="contentdivider"><table border="0" cellpadding="0" cellspacing="0" width="100%" class="grey4">
<tr><td><img src="/im/a.gif" width="1" height="4" border="0" alt=" " /></td></tr></table></div>
<!--  END VCD4 BYLINE AND TOOLS  -->
<p><A HREF="/developer/technicalArticles/">Articles Index</A></p>
<IMG SRC=truck1.gif WIDTH="158" HEIGHT="94" ALT="" ALIGN=LEFT>
The Reference Object application programming interface (API) is 
new in the Java Development Kit 
(JDK) 1.2. This API allows a program 
to maintain special references to objects that allow the program to 
interact with the garbage collector in limited ways. Not all programs 
require this level of interaction with the garbage collector. For 
example, a program that keeps a lot of objects in memory or a program 
that needs to perform cleanup operations on related objects before an 
object is reclaimed might be good candidates for using the Reference 
Objects API.
</P>
<UL>
<LI>
A web-based program might display a lot of images when an end 
user goes to a particular page on the web.  If the end user leaves 
the page, it is not always certain he or she will return.  Such a 
program can use reference objects to create a situation where the 
garbage collector reclaims the images when heap memory runs low. 
In the event the end user returns to the page, the program can 
reload the image if it has been reclaimed.</LI>
<LI>
A program can use a reference queue to create a situation where 
the program is notified when a certain object is reachable only through 
reference objects. Upon notification, the program can proceed with 
clean-up operations on other related objects to make them eligible 
for garbage collection at the same time.</LI>
</UL>
Because it is essential to understand garbage collection before you
can understand how reference objects work, this article begins by
describing how garbage collection works when no reference objects are
involved, followed by a discussion of how things change when
reference objects are added to the heap.
<H3>Vanilla Garbage Collection</H3>
<P>
The garbage collector's job is to identify objects that are no longer
in use and reclaim the memory.  What does it mean for an object to be 
<EM>in use</EM>? 
</P>
<P>
<BLOCKQUOTE>
<STRONG>Note</STRONG>: An object is in use if it can be accessed or
<EM>reached</EM> by the program in its current state. 
</BLOCKQUOTE>
</P>
<P>
An executing Java program consists
of a set of threads, each of which is actively executing a set of methods
(one having called the next). Each of these methods can have arguments
or local variables that are references to objects. These references
are said to belong to a <EM>root set</EM> of references that are
immediately accessible to the program. Other references in the root
set include static reference variables defined in loaded classes, and
references registered through the 
<A HREF="/docs/books/tutorial/native1.1/index.html">Java 
Native Interface (JNI)</A> API.
</P>
<P>
All objects referenced by this root set of references are said to be
<EM>reachable</EM> by the program in its current state and must not 
be collected. Also, those objects might contain references to still
other objects, which are also reachable, and so on. 
</P>
<P>
All other objects on the heap are considered <EM>unreachable</EM>, and 
all unreachable objects are eligible for garbage collection. If an
unreachable object has a finalize() method, arrangements are made for 
the object's finalizer to be called.  Unreachable objects with no
finalizers and objects whose finalizers have been called are
simply reclaimed during garbage collection.
</P>
<P>
Garbage collection algorithms vary, but they all have in common the
task of identifying the objects that are reachable from the root
set and reclaiming the space occupied by any other objects.
</P>
<P>
In the diagram, which is a simplified view of the stack and heap for
instructional purposes, objects inside the blue square are reachable 
from the thread root set, while objects outside the square 
(in red) are not. 
</P>
<P>
<IMG SRC="/developer/technicalArticles/ALT/RefObj/reach.gif" WIDTH="450" HEIGHT="323" ALT="" ALIGN=CENTER>
</P>
<P>
<DIV ALIGN=LEFT><EM>Fig.1: How garbage collection works.</EM></DIV>
</P>
<P>
An object may refer to reachable objects and still be unreachable
itself. Likewise, an object can be unreachable in spite of
references to it, if those references are all from unreachable
objects.
</P>
<BLOCKQUOTE>
<!-- BEGIN FRAGMENT | HR TAG -->
<div class="contentdivider"><table border="0" cellpadding="0" cellspacing="0" width="100%" class="grey4"><tr><td><img src="/im/a.gif" width="1" height="4" border="0" alt=" " /></td></tr></table></div>
<!-- END FRAGMENT | HR TAG -->
<STRONG>Conservative Garbage Collection:</STRONG> If you use the
<A HREF="/docs/books/tutorial/native1.1/index.html">Java 
Native Interface (JNI)</A> API to make C calls, the garbage collector 
might see something in memory created by the C code that looks like a 
pointer, but is actually garbage. In this case, the memory is not garbage 
collected because the Java VM is conservative and does not reclaim memory 
that looks like it could be allocated to a pointer.
<!-- BEGIN FRAGMENT | HR TAG -->
<div class="contentdivider"><table border="0" cellpadding="0" cellspacing="0" width="100%" class="grey4"><tr><td><img src="/im/a.gif" width="1" height="4" border="0" alt=" " /></td></tr></table></div>
<!-- END FRAGMENT | HR TAG -->
</BLOCKQUOTE>
<H3>What Happens When You Use Reference Objects</H3>
<P>
How does the introduction of reference objects change things?
Unlike ordinary references, the reference in a reference object 
is treated specially by the garbage collector. A reference object 
encapsulates a reference to some other object, which is called the 
<EM>referent</EM>.
</P>
<P>
The referent of a reference object is specified when the reference 
object is created.  In the following code, <CODE>image</CODE> is an 
image object passed to <CODE>sr</CODE>, a SoftReference object. The
<CODE>image</CODE> object is the referent of <CODE>sr</CODE>, and the 
reference field in <CODE>sr</CODE> is a soft reference to 
<CODE>image</CODE>.
</P>
<!-- BEGIN VCD7 CODE SAMPLE COMPONENT  -->
<table border="0" cellpadding="10" cellspacing="0" width="100%" class="grey4">
<tr><td><PRE>
  Image image = (
    sr == null) ? null : (Image)(sr.get());
  if (image == null) {
    image = getImage(getCodeBase(), &quot;truck1.gif&quot;);
    sr = new SoftReference(image);
  }
  </PRE></td></tr></table>
<span class="sp20"> </span><br />
<!-- END VCD7 CODE SAMPLE COMPONENT  -->
<H3>Object Reachability</H3>
<P>
Besides strongly reachable and unreachable objects, the Reference 
Objects API gives you strengths of object reachability. You can have 
softly, weakly and phantomly reachable objects and gain a limited 
amount of interaction with the garbage collector according to the 
strength of the object's reachability.
</P>
<P>
The next sections explain these strengths and how to use them. This
section takes a look at how garbage collection is changed when two of 
the objects on the heap in Figure 1 are changed to weak reference 
objects.
</P>
<P>
When an object is reachable from the root set by some chain of ordinary 
references (no reference objects involved), that object is said to be 
<EM>strongly reachable</EM>.  If, however, the only ways to reach an 
object involve at least one weak reference object, the object is said 
to be <EM>weakly reachable</EM>. An object is considered by the garbage 
collector to be in use if it is strongly reachable.  Weakly reachable 
objects, like unreachable objects, are eligible for collection.
</P>
<P>
So, weak references allow you to refer to an object without keeping it 
from being collected.  If the garbage collector collects a weakly reachable
object, all weak references to it are set to <CODE>null</CODE> so the
object can no longer be accessed through the weak reference.
</P>
<P>
<IMG SRC="/developer/technicalArticles/ALT/RefObj/weakreach.gif" WIDTH="488" HEIGHT="316" ALT="" ALIGN=CENTER>
</P>
<P>
<DIV ALIGN=LEFT><EM>Fig.2: Adding reference objects to the heap.</EM></DIV>
</P>
<UL>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">
Unreachable objects (outside the strongly and weakly reachable 
areas) are not reachable from the root set.</FONT>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">
Strongly reachable objects (inside the strongly reachable area 
to the lower left) are reachable through at least one path that does 
not go through a reference object.</FONT>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">
Weakly reachable objects (inside the weakly reachable area shown 
enclosed with a dashed line to the upper-right) are not strongly 
reachable through any path, but reachable through at least one path 
that goes through a weak reference.</FONT>
</UL>
<P>
The diagram above shows two paths to the object on the heap with the
<EM>X</EM>. It can be reached through the weak reference, and directly 
from the stack without going through a weak reference object. The object 
with the <EM>X</EM> is strongly reachable and not weakly reachable because 
one path leads to it from the root set without going through a reference 
object. The garbage collection behavior for this object is the same as other 
strongly reachable objects until it is no longer reachable from the root set, 
at which time it becomes weakly reachable.
</P>
<P>
Here is another way to look at the same idea:
</P>
<P>
<IMG SRC="/developer/technicalArticles/ALT/RefObj/strongweak.gif" WIDTH="383" HEIGHT="345" ALT="">
</P>
<P>
<DIV ALIGN=LEFT><EM>Fig.3: References suspended from a beam.</EM></DIV>
</P>
<P>
Imagine the root set of references as a solid beam from which objects
are suspended by cables (strong references).  An object might contain
references to other objects. Weak reference objects connect to their
referent not by a cable, but by a flexible rubber band, no number of
which could support an object.  Objects not held by cables fall into
the garbage bin below.
</P>
<P>
The Reference Objects API provides several types of reference objects, 
which gives a program several strengths of object reachability once the 
referent is no longer strongly reachable. The next section explains the 
different types of reference objects and what is meant by strengths of 
reachability.
</P>
<H3>All About Reference Objects</H3>
<P>
The Reference Objects API consists of the classes listed below and
shown in the figure.
</P>
<P>
<IMG SRC="/developer/technicalArticles/ALT/RefObj/classes.gif" WIDTH="394" HEIGHT="232" ALT="">
</P>
<DIV ALIGN=LEFT><EM>Fig.4: Class hierarchy diagram.</EM></DIV>
<P>
The <CODE>SoftReference</CODE>, <CODE>WeakReference</CODE>, and 
<CODE>PhantomReference</CODE> classes define three kinds of reference 
objects and three strengths of object reachability. From strongest to 
weakest, the strengths of reachability are the following:
</P>
<UL>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">
Strongly reachable</FONT>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">
Softly rechable</FONT>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">
Weakly reachable</FONT>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">
Phantomly reachable</FONT>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">
Unreachable</FONT>
</UL>
<P>
See the <A HREF="/products/jdk/1.2/docs/api/index.html">JDK 
1.2 API specification</A> for the class and method descriptions:
</P>
<H3>Strengths of Reachability</H3>
<P>
The Reference Objects API defines strengths of object reachability. You 
can have (going from strongest to weakest) softly, weakly and phantomly 
reachable objects and gain an amount of interaction with the garbage 
collector according to the strength of an object's reachability.
</P>
<P>
There is no limit to the number or type of references there can be to an 
object. One object can be referenced by any mix of strong, soft, weak, 
and phantom references depending on your application requirements.
</P>
<P>
To determine an object's strength of reachability, the garbage collector 
starts at the root set and traces all the paths to objects on the heap. 
The reference objects that the garbage collector goes through to reach 
an object are what determine the reachability of that object. When any 
path to an object is free of reference objects, the object is strongly
reachable. When all paths have one or more reference objects, the object
is softly, weakly, or phantomly reachable according to the type of reference
object(s) the garbage collector finds.  In general, an object is only as 
reachable as the weakest link in the strongest path from the root set. The 
sections to follow describe how this all works.
</P>
<H3>Softly Reachable</H3>
<P>
An object is <EM>softly reachable</EM> if it is not strongly reachable and 
there is a path to it with no weak or phantom references, but one or more 
soft references. The garbage collector might or might not reclaim a softly 
reachable object depending on how recently the object was created or accessed,
but is required to clear all soft references before throwing an 
<CODE>OutOfMemoryError</CODE>.
</P>
<P>
If heap memory is running low, the garbage collector may, at its own 
discretion, find softly reachable objects that have not been accessed 
in the longest time and clear them (set their reference field to 
<CODE>null</CODE>).
</P>
<P>
<CODE>SoftReference</CODE> objects work well in applications that, for 
example, put a large number of images into memory and there is no way to 
know if the application (driven by end user input) will access a given 
image again. If the garbage collector reclaims an image that has not been 
accessed for a long time, and the application needs to access it again, 
the application reloads the image and displays it.
</P>
<H3>Using Soft References in Web-Based Programs</H3>
<P>
Soft references are very useful in web-based programs where, for example, 
an applet creates an image to display on a web page. When the user opens 
the web page, the applet code gets the image and displays it. If the code 
also creates a soft reference to the image, the garbage collector has the 
option to reclaim or not reclaim the memory allocated to the image when the 
user moves to another web page. Here is how the example application looks 
in memory: 
</P>
<P>
<IMG SRC="/developer/technicalArticles/ALT/RefObj/softreach.gif" WIDTH="450" HEIGHT="228" ALT=""ALIGN=CENTER>
</P>
<P>
<DIV ALIGN=LEFT><EM>Fig.5: Using soft references.</EM></DIV>
</P>
<P>
If the user returns to the web page where the image is, the applet code 
uses the SoftReference.get method to check the soft reference to find 
out if the image is still in memory. If the image has not been reclaimed 
by the garbage collector, it is quickly displayed on the page; and if the 
image has been reclaimed, the applet code gets it again. 
</P>
<P>
If your program calls the SoftReference.clear method, the reference may 
become eligible for reclamation.  However, if there is a strong reference 
to the object, calling the clear method does not cause the garbage
collector to reclaim the object. In this case, the soft reference is null, 
but garbage collection does not happen until the object is no longer strongly 
reachable. 
</P>
<P>
Here is the complete <A HREF="/developer/technicalArticles/ALT/RefObj/DisplayImage.java">DisplayImage.java</A> 
source code.
</P>
<BLOCKQUOTE>
<STRONG>NOTE</STRONG>: The <CODE>im</CODE> object is set to <CODE>null</CODE> 
because there is no gurantee the stack slot occupied by it will be cleared 
when it goes out of scope.  A later method invocation whose stack frame
contains the slot previously occupied by <CODE>im</CODE> might not put a 
new value there, in which case, the garbage collector still considers the 
slot to contain a root.
<P>
This is a problem even with non-conservative exact collectors. As a
precaution, you can increase the probability that an object will become 
softly, weakly, finalizable, or phantomly reachable by clearing variables 
that refer to it.
</P>
</BLOCKQUOTE>
<!-- BEGIN VCD7 CODE SAMPLE COMPONENT  -->
<table border="0" cellpadding="10" cellspacing="0" width="100%" class="grey4">
<tr><td><PRE><CODE>

import java.awt.Graphics;
import java.awt.Image;
import java.applet.Applet;
import java.lang.ref.SoftReference;

public class DisplayImage extends Applet {

        SoftReference sr = null;

        public void init() {
            System.out.println(&quot;Initializing&quot;);
        }

        public void paint(Graphics g) {
            Image im = (
              sr == null) ? null : (Image)(
              sr.get());
            if (im == null) {
                System.out.println(
                &quot;Fetching image&quot;);
                im = getImage(getCodeBase(),
                   &quot;truck1.gif&quot;);
                sr = new SoftReference(im);
           }
           System.out.println(&quot;Painting&quot;);
           g.drawImage(im, 25, 25, this);
           im = null;  
        /* Clear the strong reference to the image */
        }

        public void start() {
            System.out.println(&quot;Starting&quot;);
        }

        public void stop() {
            System.out.println(&quot;Stopping&quot;);
        }

}

</CODE></PRE></td></tr></table>
<span class="sp20"> </span><br />
<!-- END VCD7 CODE SAMPLE COMPONENT  -->
<H3>Reference Queues</H3>
<P>
A
<A HREF="/products/jdk/1.2/docs/api/java.lang.ref.ReferenceQueue.html">java.lang.ref.ReferenceQueue</A>
is a simple data structure onto which the garbage collector places reference
objects when the reference field is cleared (set to <CODE>null</CODE>).
You would use a reference queue to find out when an object becomes softly, 
weakly, or phantomly reachable so your program can take some action based 
on that knowledge. For example, a program might perform some post-finalization 
cleanup processing that requires an object to be unreachable (such as the 
deallocation of resources outside the Java heap) upon learning that an 
object has become phantomly reachable.
</P>
<P>
To be placed on a reference queue, a reference object must be created with
a reference queue. Soft and weak reference objects can be created with
a reference queue or not, but phantom reference objects must be created
with a reference queue:
</P>
<PRE>
  ReferenceQueue queue = new ReferenceQueue();
  PhantomReference pr = 
    new PhantomReference(object, queue);
  </PRE>
<P>
Another approach to the soft reference example from the diagram
on the previous page could be to create the SoftReference objects
with a reference queue, and poll the queue to find out when an image
has been reclaimed (its reference field cleared). At
that point, the program can remove the corresponding entry from the
hash map, and thereby, allow the associated string to be garbage
collected.
</P>
<BLOCKQUOTE>
<!-- BEGIN FRAGMENT | HR TAG -->
<div class="contentdivider"><table border="0" cellpadding="0" cellspacing="0" width="100%" class="grey4"><tr><td><img src="/im/a.gif" width="1" height="4" border="0" alt=" " /></td></tr></table></div>
<!-- END FRAGMENT | HR TAG -->
<STRONG>Note</STRONG>: A program can also wait indefinitely on a reference 
queue with the <CODE>remove()</CODE> method, or for a bounded amount of 
time with the <CODE>remove(long timeout)</CODE> method.
<!-- BEGIN FRAGMENT | HR TAG -->
<div class="contentdivider"><table border="0" cellpadding="0" cellspacing="0" width="100%" class="grey4"><tr><td><img src="/im/a.gif" width="1" height="4" border="0" alt=" " /></td></tr></table></div>
<!-- END FRAGMENT | HR TAG -->
</BLOCKQUOTE>
<P>
Soft and weak reference objects are placed in their reference queue some
time after they are cleared (their reference field is set to <CODE>null</CODE>).
Phantom reference objects are placed in their reference queue after they
become phantomly reachable, but before their reference field is cleared. 
This is so a program can perform post-finalization cleanup and clear the
phantom reference upon completion of the cleanup.
</P>
<H3>Weakly Reachable</H3>
<P>
An object is weakly reachable when the garbage collector finds no strong
or soft references, but at least one path to the object with a weak reference. 
Weakly reachable objects are finalized some time after their weak references 
have been cleared. The only real difference between a soft reference and a 
weak reference is that the garbage collector uses algorithms to decide whether 
or not to reclaim a softly reachable object, but always reclaims a weakly 
reachable object.
</P>
<P>
Weak references work well in applications that need to, for example, 
associate extra data with an unchangeable object, such as a thread the 
application did not create. If you make a weak reference to the thread 
with a reference queue, your program can be notified when the thread is 
no longer strongly reachable. Upon receiving this notification, the program 
can perform any required cleanup of the associated data object.
</P>
<P>
To make the Thread object weakly reachable, its strong reference must be 
set to <CODE>null</CODE>.  After the garbage collector clears the weak 
reference to the thread, it places the weak reference on the queue. When 
the program removes the reference from the queue, it can then remove the 
corresponding hash map entry, and thereby, allow the data object to be 
reclaimed.
</P>
<P>
<IMG SRC="/developer/technicalArticles/ALT/RefObj/weakreach2.gif" WIDTH="450" HEIGHT="319" ALT="" ALIGN=CENTER>
</P>
<P>
<DIV ALIGN=LEFT><EM>Fig.6: Using weak references.</EM></DIV>
</P>
<P>
The following code examples stores an object and some extra data in a hash 
map. The object is referenced by a weak reference object that was created 
with a reference queue.  This is a very simple code example to illustrate 
the points discussed in this article. In a real application, the data would 
be associated with the object well after the object is created; otherwise, 
you could keep the data in a subclass of the object instead of using a weak 
reference.
</P>
<P>
After the object becomes weakly reachable, the garbage collector clears the 
weak reference and places it in the reference queue. The code queries the 
reference queue for the weak reference, and upon finding the weak reference 
there, sets the reference to the extra data to <CODE>null</CODE> so the extra 
data is garbage-collected after the object is.
</P>
<P>
An important point in this example is that the object can be reached from 
the stack through two paths: one path goes through the weak reference and 
the other goes through the hash map.  The object does not become weakly 
reachable until the reference to it in the hash map is null. It is not 
enough to just set the object to null.
</P>
<P>
Here is the complete <A HREF="/developer/technicalArticles/ALT/RefObj/WeakObj.java>WeakObj.java"></A> source code.
</P>
<!-- BEGIN VCD7 CODE SAMPLE COMPONENT  -->
<table border="0" cellpadding="10" cellspacing="0" width="100%" class="grey4">
<tr><td><PRE><CODE>
import java.lang.ref.*;
import java.util.*;

public class WeakObj {

 public static void main(String[] args) {
  try {
    ReferenceQueue aReferenceQueue 
      = new ReferenceQueue();
    Object anObject = new Object();
    WeakReference ref = new WeakReference(anObject,
                                 aReferenceQueue);
    String extraData = new String(&quot;Extra Data&quot;);
    HashMap aHashMap = new HashMap();;

//Associate extraData (value) with weak reference
// (key) in aHashMap
    aHashMap.put(ref, extraData);

//Check that a reference to an object was created
    System.out.println(
      &quot;*** created ref to some object&quot;);
    System.out.println();
    System.out.println(
      &quot;contents of ref: &quot; + ref.get());
    System.out.println();


//Check whether the Reference Object is enqueued
    System.out.println(
      &quot;ref.isEnqueued(): &quot; + ref.isEnqueued());
    System.out.println();

//Clear the strong reference to anObject
    anObject = null;

//Clear the strong reference to extraData
    if(anObject == null){
      extraData = null;
    }
//Run the garbage collector, and
//Check the reference object's referent
    System.out.println(&quot;*** running gc...&quot;);
    System.gc();
    System.out.println();
    System.out.println(
      &quot;contents of ref: &quot; + ref.get());
    System.out.println();


//Check whether the reference object is enqueued
    System.out.println(
      &quot;ref.isEnqueued(): &quot; + ref.isEnqueued());
    System.out.println();

//Enqueue the reference object. 
//This method returns false
//if the reference object is already enqueued.
    System.out.println(&quot;enqueued=&quot;+ref.enqueue());

  } catch (Exception e) {
    System.err.println(&quot;An exception occurred:&quot;);
    e.printStackTrace();
  }
 }
}
</CODE></PRE></td></tr></table>
<span class="sp20"> </span><br />
<!-- END VCD7 CODE SAMPLE COMPONENT  -->
<H3>Phantomly Reachable</H3>
<P>
An object is phantomly reachable when the garbage collector finds no
strong, soft, or weak references, but at least one path to the object 
with a phantom reference. Phantomly reachable objects are objects that 
have been finalized, but not reclaimed. 
</P>
<P>
When the garbage collector finds only phantom references to an object, 
it enqueues the phantom reference. The program polls the reference queue 
and upon notification that the phantom reference is enqueued, performs 
post-finalization cleanup processing that requires the object to be 
unreachable (such as the deallocation of resources outside the Java heap). 
At the end of the post-finalization cleanup code, the program should call 
the <CODE>clear()</CODE> method on  the phantom reference object to set 
the reference field to <CODE>null</CODE> to make the referent eligible 
for garbage collection.
</P>
<H2>Chains of reference objects</H2>
<P>
A given path to an object can contain more than one kind of reference
object, which creates a chain of reference objects. The garbage collector
processes reference objects in order from strongest to weakest. The
processing always happens in the following order, but there is no guarantee
when the processing will occur:
</P>
<UL>
<LI>Soft references</LI>
<LI>Weak references</LI>
<LI>Finalization</LI>
<LI>Phantom references</LI>
<LI>Reclamation</LI>
</UL>
<P>
In the diagram below, there is a chain of reference objects to Some Object. 
When the garbage collector processes the reference objects, will it find 
Some Object to be phantomly, weakly, or softly reachable?
</P>
<P>
<IMG SRC="/developer/technicalArticles/ALT/RefObj/chain.gif" WIDTH=327 HEIGHT=361 ALT="" ALIGN=CENTER>
</P>
<P>
<DIV ALIGN=LEFT><EM>Fig.7: How reachable is some object?.</EM></DIV>
</P>
<P>
The answer is Some object is phantomly reachable.  In general an object is 
only as reachable as the weakest link in the strongest path from a root set. 
In the diagram, the phantom reference is strongly reachable, but all other 
objects are phantomly reachable.
</P>
<P>
However, if the weak reference is strongly reachable as shown in the next 
diagram, both Phantom and Weak reference are strongly reachable, and Soft 
reference and Some object are weakly reachable.
</P>
<P>
<IMG SRC="/developer/technicalArticles/ALT/RefObj/chain2.gif" WIDTH=327 HEIGHT=361 ALT="" ALIGN=CENTER>
</P>
<P>
<DIV ALIGN=LEFT><EM>Fig.8: Phantomly or weakly reachable?.</EM></DIV>
</P>
<P>
Can you guess what happens if Soft reference is strongly reachable?
</P>
<P>
<IMG SRC="/developer/technicalArticles/ALT/RefObj/chain3.gif" WIDTH=327 HEIGHT=361 ALT="" ALIGN=CENTER>
</P>
<P>
<DIV ALIGN=LEFT><EM>Fig. 9: Phantomly, weakly, or softly reachable?.</EM></DIV>
</P>
<P>
The answer is Phantom, Weak, and Soft reference are strongly reachable, 
and Some Object is softly reachable.
</P>
<H3>WeakHashMap Class</H3>
<P>
A <CODE>WeakHashMap</CODE> object is like a <CODE>HashMap</CODE> object in
that it stores key-value pairs where the key is an arbitrary object. But, in 
a <CODE>WeakHashMap</CODE> object, the key is referenced by a weak reference 
object internal to the <CODE>WeakHashMap</CODE> object.
</P>
<P>
After the object referenced by the weak key becomes weakly reachable, the 
garbage collector clears the internal weak reference. At this point, the 
key and its associated value become eligible for finalization, and if there 
are no phantom references to the key, the key and value then become eligible 
for reclamation. The WeakHashMap class provides a weak hash table facility, 
but in a class that fits into the new 
<A HREF="/docs/books/tutorial/collections/index.html">Collections</A>
framework.
</P>
<P>
If you use a <CODE>WeakHashMap</CODE> object instead of the <CODE>HashMap</CODE> 
and <CODE>WeakReference</CODE> objects, you can associate pairs of objects as 
keys and values. The value is made eligible for garbage collection when the 
key becomes weakly reachable. This uses fewer lines of code because you do not 
need a <CODE>WeakReference</CODE> object, and you do not have to explicitly set 
the associated object to <CODE>null</CODE>.
</P>
<H3>Conclusion</H3>
<P>
If you have ever wanted the garbage collector to reclaim unused objects when 
heap memory is running low, or a convenient way to be sure an object is 
collected when an object it is related to is no longer in use, the JDK 1.2
Reference Objects API is for you. Not only do you get some control over
garbage collection, but your programs will run better too. 
</P>
<P>
<IMG SRC="/images/coffeecup13x10.gif" WIDTH="13" HEIGHT="10" ALT="coffeecup">
</P>
<a name="author"></a>
<p>
<A HREF="/people/monicap">Monica Pawlan</A>,
a staff writer for the Java Developer
Connection (JDC), is
author of <I>Essentials of the Java Programming Language: A Hands-On
Guide</I> (Addison-Wesley, 2000), and co-author of <I>Advanced Programming
for the Java 2 Platform</I> (Addison-Wesley, 2000).
</P>
<!-- =================== -->
<!-- END OF MAIN CONTENT -->
<!-- =================== -->
<!--stopindex-->
<!-- END CENTRAL COLUMN COMPONENTS -->
</td><td valign="top">
<!-- BEGIN RIGHT COLUMN COMPONENTS -->
<!-- END RIGHT COLUMN COMPONENTS -->
</td></tr>
<!-- BEGIN SPACER ROW -->
<tr><td><img src="/im/a.gif" width="560" height="1" border="0" alt=" " /></td><td><img src="/im/a.gif" width="170" height="1" border="0" alt=" " /></td></tr>
<!-- END SPACER ROW -->
</table>
<!-- END WRAPPER TABLE, 2 COLUMN, MAIN/RIGHT -->
<!-- BEGIN VNV5 FOOTER  -->
<table border="0" cellpadding="0" cellspacing="10" width="100%">
<tr>
<td>
<table border="0" cellpadding="0" cellspacing="0" width="100%" class="vatop">
<tr>
<td colspan="4" valign="top" class="grey3"><img src="/im/a.gif" width="1" height="2" border="0" alt="" /></td></tr>
<tr>
<td><img src="/im/a.gif" width="190" height="1" border="0" alt="" /><br />
<a href="http://www.sun.com"><img src="/im/logo_sun_small_sdn.gif" width="61" height="29" border="0" alt="" vspace="5"/></a></td>
<td width="100%" valign="top"><img src="/im/a.gif" width="350" height="1" border="0" alt="" /><br />
<div class="footer">
<a href="http://developers.sun.com/global/aboutsun.html">About Sun</a> &nbsp;|&nbsp;
<a href="http://developers.sun.com/global/aboutsdn.html">About This Site</a> &nbsp;|&nbsp;
<a href="http://developers.sun.com/global/newsletters.html">Newsletters</a> &nbsp;|&nbsp;
<a href="http://developers.sun.com/global/contact.html">Contact Us</a> &nbsp;|&nbsp;
<a href="http://developers.sun.com/global/employment.html">Employment</a><br />
<a href="http://developers.sun.com/global/howtobuy.html">How to Buy</a> &nbsp;|&nbsp;
<a href="http://developers.sun.com/global/licensing.html">Licensing</a> &nbsp;|&nbsp;
<a href="http://developers.sun.com/global/termsofuse.html">Terms of Use</a> &nbsp;|&nbsp;
<a href="http://developers.sun.com/global/privacy.html">Privacy</a> &nbsp;|&nbsp;
<a href="http://developers.sun.com/global/trademarks.html">Trademarks</a>
<br /><span class="sp10">&nbsp;</span><br />
<br /><span class="sp10">&nbsp;</span><br />
Copyright <span id="copyDate" class="cssDate"></span> Sun Microsystems, Inc.
</div></td>
<td><img src="/im/a.gif" width="40" height="1" border="0" alt="" /></td>
<td valign="top"><div class="footer"><b><a href="http://developers.sun.com/global/aboutsdn.html">A Sun Developer Network Site</a></b></div>
<div class="footer">
<img src="/im/a.gif" width="170" height="1" border="0" alt="" /><br />
Unless otherwise licensed, code in all technical manuals herein (including articles, FAQs, samples) is provided under this <a href="http://developers.sun.com/global/berkeley_license.html">License</a>.
<br /><span class="sp5">&nbsp;</span><br />
<a href="http://developers.sun.com/global/rss_sdn.html"><img src="/im/button_xml.gif" width="36" height="14" align="top" border="0" alt="XML" /></a>&nbsp;<a href="http://developers.sun.com/global/content_feeds.html">Content Feeds</a>
</div></td></tr>
<tr><td colspan="4" valign="top" class="grey3"><img src="/im/a.gif" width="1" height="2" border="0" alt="" /></td></tr>
</table>
</td></tr>
</table>
<!-- END VNV5 FOOTER -->
</body>
<script language="JavaScript" src="/js/omi/jsc/s_code_remote.js"></script></html>



