<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Shadow &#38; Honnix &#187; Reference</title>
	<atom:link href="http://honnix.com/blog/archives/tag/reference/feed" rel="self" type="application/rss+xml" />
	<link>http://honnix.com/blog</link>
	<description>she&#039;s growing up</description>
	<lastBuildDate>Sun, 15 Jan 2012 10:44:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.1</generator>
		<item>
		<title>Java里面的Reference</title>
		<link>http://honnix.com/blog/archives/55</link>
		<comments>http://honnix.com/blog/archives/55#comments</comments>
		<pubDate>Mon, 14 Jan 2008 13:25:08 +0000</pubDate>
		<dc:creator>honnix</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[GC]]></category>
		<category><![CDATA[Reference]]></category>

		<guid isPermaLink="false">http://honnix.oicp.net:8080/blog/?p=55</guid>
		<description><![CDATA[之前写过一篇关于Java Reference的文章，只放了一个链接；这个星期要开Java的Workshop，所以仔细研究了一把。 首先是对几个Reachable作定义（其实是从Java Doc抄来的，翻得我实在不爽，直接看Java Doc吧） ： Strongly Reachable──一个对象是strongly reachable的，当且仅当它能够被某个线程reach到而不需要通过任何的Reference Object Weakly Reachable──一个对象是weakly reachable的，当且仅当它不是strongly reachable的，而且仅通过Soft Reference就可以被查找到 Phantom Reachable──一个对象是phantom reachable的，当且仅当它既不是strongly reachable的，也不是weakyly reachable的，它已经被finalized了，而且有一些Phantom Reference指向它 Phantom Reference： 如果在ReferenceQueue里面读到了一个Phantom Reference对象，说明该reference的referent已经被finalized了，如果它是finalizable的（这样的话需要两次GC才能在ReferenceQueue里面读到），否则一但referent成为phantom reachable的时候reference就被放入ReferenceQueue中。 实验表明，如果referent是finalizable的话，要经过两次GC之后才能在ReferenQueue里面读到Phantom Reference，第一次GC时，referent被finalized，但Phantom Reference不会被放到队列中。 如果new一个Phantom Reference的时候不传给它一个ReferenceQueue，那这个reference几乎没有任何用处，因为PhantomReference.get()永远返回null。 需要注意的是，GC不会调用PhantomReference.clear()，如果不对它显示地进行clear，那么它所引用到的对象就一直以finalized过的状态待在堆里而不被真正的回收，除非所有指向它的Phantom Reference都被clear了，或者它本身变为unreachable了。这一点和Weak Reference以及Soft Reference都不一样。 Phantom Reference一般用来处理一些cleanup的事情：监视某个对象，如果它被finalized之后，释放资源。例如：一个大的图片对象被finalized之后，那么用来读取和处理它的其它一些资源就可以被释放掉了。 Weak Reference： 如果在ReferenceQueue里面读到了一个Weak Reference对象，并不能说明该reference的referent已经被finalized了 所有对象的finalization都由一个FinalizeQueue来处理，这个queue本身就是一个线程；当GC发现一个对象是Weakly Reachable的时候，就会把它的reference放到ReferenceQueue中，而把这个对象放到FinalizeQueue中；这两个动作的先后顺序我还不是很清楚，但似乎不是特别重要，这里只要知道由这么两件事情应该就足够了 GC会主动调用WeakReference.clear()，这一点和Soft Reference相同。这样，即使没有ReferenceQueue我们也可以知道一个对象什么时候被GC发现成为weakly reachable，只要WeakReference.get() == null就可以了。 Weak Reference一般用来实现一些容器，我们不需要对容器的引用显示地清理（container[i] = null）以防止内存泄露。比较有名就是JDK中的WeakHashMap，它的key是Weak Reference，当key成为weakly reachable的时候，key&#38;value在就会被清除出去。这样一来，我们可以用map保存对象引用，以及它的一些附加信息，当这样对象不再是strongly reachable的时候，我们不必手工清理map，一切都交给GC去做了。&#8230;]]></description>
			<content:encoded><![CDATA[<p>之前写过一篇关于Java Reference的文章，只放了一个链接；这个星期要开Java的Workshop，所以仔细研究了一把。</p>
<p><span id="more-55"></span></p>
<p>首先是对几个Reachable作定义（其实是从Java Doc抄来的，翻得我实在不爽，直接看Java Doc吧） ：</p>
<ol>
<li>Strongly Reachable──一个对象是strongly reachable的，当且仅当它能够被某个线程reach到而不需要通过任何的Reference Object</li>
<li>Weakly Reachable──一个对象是weakly reachable的，当且仅当它不是strongly reachable的，而且仅通过Soft Reference就可以被查找到</li>
<li>Phantom Reachable──一个对象是phantom reachable的，当且仅当它既不是strongly reachable的，也不是weakyly reachable的，它已经被finalized了，而且有一些Phantom Reference指向它</li>
</ol>
<p><u>Phantom Reference</u>：</p>
<ul>
<li>如果在ReferenceQueue里面读到了一个Phantom  Reference对象，说明该reference的referent已经被finalized了，如果它是finalizable的（这样的话需要两次GC才能在ReferenceQueue里面读到），否则一但referent成为phantom reachable的时候reference就被放入ReferenceQueue中。</li>
<li>实验表明，如果referent是finalizable的话，要经过两次GC之后才能在ReferenQueue里面读到Phantom Reference，第一次GC时，referent被finalized，但Phantom Reference不会被放到队列中。</li>
<li>如果new一个Phantom Reference的时候不传给它一个ReferenceQueue，那这个reference几乎没有任何用处，因为PhantomReference.get()永远返回null。</li>
<li>需要注意的是，GC不会调用PhantomReference.clear()，如果不对它显示地进行clear，那么它所引用到的对象就一直以finalized过的状态待在堆里而不被真正的回收，除非所有指向它的Phantom Reference都被clear了，或者它本身变为unreachable了。<font color="#ff0000">这一点和Weak Reference以及Soft Reference都不一样。</font></li>
<li>Phantom Reference一般用来处理一些cleanup的事情：监视某个对象，如果它被finalized之后，释放资源。例如：一个大的图片对象被finalized之后，那么用来读取和处理它的其它一些资源就可以被释放掉了。</li>
</ul>
<p><u>Weak Reference</u>：</p>
<ul>
<li> 如果在ReferenceQueue里面读到了一个Weak Reference对象，并不能说明该reference的referent已经被finalized了</li>
<li>所有对象的finalization都由一个FinalizeQueue来处理，这个queue本身就是一个线程；当GC发现一个对象是Weakly Reachable的时候，就会把它的reference放到ReferenceQueue中，而把这个对象放到FinalizeQueue中；这两个动作的先后顺序我还不是很清楚，但似乎不是特别重要，这里只要知道由这么两件事情应该就足够了</li>
<li>GC会主动调用WeakReference.clear()，<font color="#ff0000">这一点和Soft Reference相同。<font color="#000000">这样，即使没有ReferenceQueue我们也可以知道一个对象什么时候被GC发现成为weakly reachable，只要WeakReference.get() == null就可以了。</font></font></li>
<li><font color="#ff0000"><font color="#000000">Weak Reference一般用来实现一些容器，我们不需要对容器的引用显示地清理（container[i] = null）以防止内存泄露。比较有名就是JDK中的WeakHashMap，它的key是Weak Reference，当key成为weakly reachable的时候，key&amp;value在就会被清除出去。这样一来，我们可以用map保存对象引用，以及它的一些附加信息，当这样对象不再是strongly reachable的时候，我们不必手工清理map，一切都交给GC去做了。</font></font></li>
</ul>
<p><u>Soft Reference</u>：</p>
<ul>
<li>Soft Reference和Weak Reference非常类似，只有一点最大的区别：当一个对象变成Soft Reachable状态的时候，它不一定被GC回收（或者说有很大可能不会被回收），具体行为由虚拟机实现决定，唯一能保证的是，在虚拟机抛出OutOfMemory异常之前，这个对象肯定已经被回收了。</li>
<li>Soft Reference的这个特定使得它非常适合做cache，用Soft Reference引用一个大对象，这个对象在某些时候是strongly reachable的，而有些时候又不需要，那么由虚拟机来确定什么时候回收它吧，如果它被回收，那么SoftReference.get()出来的东西就是null，这时候只要再重新实例化一个对象就可以了。</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://honnix.com/blog/archives/55/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

