java reference

import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.concurrent.TimeUnit;

public class ReferenceTest {
/*
 *
SoftReference
	SoftReference 在“弱引用”中属于最强的引用。SoftReference 所指向的对象,当没有强引用指向它时,会在内存中停留一段的时间,
	垃圾回收器会根据 JVM内存的使用情况(内存的紧缺程度)以及 SoftReference 的 get() 方法的调用情况来决定是否对其进行回收。
	具体使用一般是通过 SoftReference 的构造方法,将需要用弱引用来指向的对象包装起来。当需要使用的时候,
	调用 SoftReference 的 get() 方法来获取。当对象未被回收时 SoftReference 的 get() 方法会返回该对象的强引用
	
	软引用有以下特征:
	1. 软引用使用 get() 方法取得对象的强引用从而访问目标对象。
	2. 软引用所指向的对象按照 JVM 的使用情况(Heap 内存是否临近阈值)来决定是否回收。
	3. 软引用可以避免 Heap 内存不足所导致的异常。
	 
	当垃圾回收器决定对其回收时,会先清空它的 SoftReference,也就是说 SoftReference 的 get() 方法将会返回 null,
	然后再调用对象的 finalize() 方法,并在下一轮 GC 中对其真正进行回收。

WeakReference
	WeakReference 是弱于 SoftReference 的引用类型。弱引用的特性和基本与软引用相似,区别就在于弱引用所指向的对象只要进行系统垃圾回收,
	不管内存使用情况如何,永远对其进行回收(get() 方法返回 null)
	 
	 弱引用有以下特征:
	1.弱引用使用 get() 方法取得对象的强引用从而访问目标对象。
    2.一旦系统内存回收,无论内存是否紧张,弱引用指向的对象都会被回收。
    3.弱引用也可以避免 Heap 内存不足所导致的异常。

PhantomReference
	PhantomReference 是所有“弱引用”中最弱的引用类型。不同于软引用和弱引用,虚引用无法通过 get() 方法来取得目标对象的强引用从而使用目标对象,
	观察源码可以发现 get() 被重写为永远返回 null。那虚引用到底有什么作用?其实虚引用主要被用来 跟踪对象被垃圾回收的状态,
	通过查看引用队列中是否包含对象所对应的虚引用来判断它是否 即将被垃圾回收,从而采取行动。它并不被期待用来取得目标对象的引用,而目标对象被回收前,
	它的引用会被放入一个 ReferenceQueue 对象中,从而达到跟踪对象垃圾回收的作用。所以具体用法和之前两个有所不同,它必须传入一个 ReferenceQueue 
	对象。当虚引用所引用对象被垃圾回收后,虚引用会被添加到这个队列中。
	
	值得注意的是,对于引用回收方面,虚引用类似强引用不会自动根据内存情况自动对目标对象回收,Client 需要自己对其进行处理以防 Heap 内存不足异常
	
	虚引用有以下特征:
	1.虚引用永远无法使用 get() 方法取得对象的强引用从而访问目标对象。
	2.虚引用所指向的对象在被系统内存回收前,虚引用自身会被放入 ReferenceQueue 对象中从而跟踪对象垃圾回收。
	3.虚引用不会根据内存情况自动回收目标对象
	
	
	小结:
	另外值得注意的是,其实 SoftReference, WeakReference 以及 PhantomReference 的构造函数都可以接收一个 ReferenceQueue 对象。
	当 SoftReference 以及 WeakReference 被清空的同时,也就是 Java 垃圾回收器准备对它们所指向的对象进行回收时,调用对象的 finalize() 方法之前,
	它们自身会被加入到这个 ReferenceQueue 对象中,此时可以通过 ReferenceQueue 的 poll() 方法取到它们。而 PhantomReference 
	只有当 Java 垃圾回收器对其所指向的对象真正进行回收时,会将其加入到这个 ReferenceQueue 对象中,这样就可以追综对象的销毁情
	
	 */
	public static void main(String[] args) throws Exception {
		// 设置jvm参数
		// -Xmx2m -Xms2m

		// test_weakReference();
		// test_weakReference2();
		// test_softReference();
		// test_phantomReference();

		// 测试oom时,把finalize方法的打印语句注释掉
		// test_strongReference_OOM();
		// test_weakReference_OOM();
		// test_softReference_OOM();
		test_phantomReference_OOM();
	}

	// result:
	// weak ref
	// weak ref is finalizing at Sat Feb 08 23:54:17 CST 2014
	// null (可能不为null,因为gc不一定执行)
	static void test_weakReference() throws Exception {
		// 声明一个弱引用
		Reference<Bean> ref = new WeakReference<Bean>(new Bean("weak ref"));
		// WeakReference通过get方法返回指向目标对象的强引用
		System.out.println(ref.get());

		// 建议jvm进行gc
		System.gc();
		System.runFinalization();
		TimeUnit.SECONDS.sleep(3);

		// 一旦jvm执行gc,会调用Reference的clear方法,清空referent,此时get方法返回值为null
		System.out.println(ref.get());
	}

	// result:
	// false
	// weak ref
	// null
	// weak ref is finalizing at Sun Feb 09 00:08:00 CST 2014
	// true
	// null
	// java.lang.ref.WeakReference@16caf43
	static void test_weakReference2() throws Exception {
		ReferenceQueue<Bean> queue = new ReferenceQueue<Bean>();
		Reference<Bean> ref = new WeakReference<Bean>(new Bean("weak ref"),
				queue);
		// 如果该引用对象被加入到关联的queue中了,返回true
		System.out.println(ref.isEnqueued());
		System.out.println(ref.get());
		System.out.println(queue.poll());

		System.gc();
		System.runFinalization();
		TimeUnit.SECONDS.sleep(3);

		System.out.println(ref.isEnqueued());
		System.out.println(ref.get());
		System.out.println(queue.poll());
	}

	// result:
	// soft ref
	// soft ref is finalizing at Sun Feb 09 00:13:29 CST 2014
	// null
	static void test_softReference() throws Exception {
		Reference<Bean> ref = new SoftReference<Bean>(new Bean("soft ref"));
		System.out.println(ref.get());

		// 模拟消耗内存操作
		SoftReference<String>[] garbage = new SoftReference[100000];
		for (int i = 0; i < garbage.length; i++) {
			garbage[i] = new SoftReference<String>(new String("gb"));
		}

		TimeUnit.SECONDS.sleep(3);

		System.out.println(ref.get());
	}

	// result:
	// null
	// false
	// null
	// phantom ref is finalizing at Sun Feb 09 00:16:26 CST 2014
	// null
	// true
	// java.lang.ref.PhantomReference@60aeb0
	static void test_phantomReference() throws Exception {
		ReferenceQueue<Bean> queue = new ReferenceQueue<Bean>();
		Reference<Bean> ref = new PhantomReference<Bean>(
				new Bean("phantom ref"), queue);
		// PhantomReference的get方法永远返回null
		System.out.println(ref.get());
		System.out.println(ref.isEnqueued());
		System.out.println(queue.poll());

		System.gc();
		TimeUnit.SECONDS.sleep(3);
		System.gc();

		System.out.println(ref.get());
		System.out.println(ref.isEnqueued());
		System.out.println(queue.poll());
	}

	static final int SIZE = 100000;

	// OOM
	static void test_strongReference_OOM() {
		Bean[] beans = new Bean[SIZE];
		for (int i = 0; i < beans.length; i++)
			beans[i] = new Bean("strong ref " + i);
	}

	// no OOM
	static void test_weakReference_OOM() {
		@SuppressWarnings("unchecked")
		Reference<Bean>[] refs = new WeakReference[SIZE];
		for (int i = 0; i < refs.length; i++)
			refs[i] = new WeakReference<Bean>(new Bean("weak ref " + i));
		System.out.println(refs[1000].get());
	}

	// no OOM
	static void test_softReference_OOM() {
		@SuppressWarnings("unchecked")
		Reference<Bean>[] refs = new SoftReference[SIZE];
		for (int i = 0; i < refs.length; i++)
			refs[i] = new SoftReference<Bean>(new Bean("soft ref " + i));
		System.out.println(refs[1000].get());
	}

	// OOM
	static void test_phantomReference_OOM() {
		ReferenceQueue<Bean> queue = new ReferenceQueue<Bean>();
		@SuppressWarnings("unchecked")
		Reference<Bean>[] refs = new PhantomReference[SIZE];
		for (int i = 0; i < refs.length; i++)
			refs[i] = new PhantomReference<Bean>(new Bean("soft ref " + i),
					queue);
	}
}

class Bean {
	String name;

	public Bean(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return name;
	}

	@Override
	protected void finalize() throws Throwable {
		// System.out.println(name + " is finalizing at " + new Date());
	}
}


参考
http://www.ibm.com/developerworks/cn/java/j-lo-langref/index.html?ca=drs-
http://zhang-xzhi-xjtu.iteye.com/blog/413159

你可能感兴趣的:(reference,soft reference,weak reference)