Java 中的 Reference

 1、强引用(StrongReference)

    强引用不会被GC回收,并且在java.lang.ref里也没有实际的对应类型。举个例子来说:
    Object obj = new Object();
    这里的obj引用便是一个强引用,不会被GC回收。

  2、软引用(SoftReference)

    软引用在JVM报告内存不足的时候才会被GC回收,否则不会回收,正是由于这种特性软引用在caching和pooling中用处广泛。软引用的用法:

Object obj = new Object();
SoftReference<Object> softRef = new SoftReference(obj);
// 使用 softRef.get() 获取软引用所引用的对象
Object objg = softRef.get();

  3、弱引用(WeakReference)

    当GC一但发现了弱引用对象,将会释放WeakReference所引用的对象。弱引用使用方法与软引用类似,但回收策略不同。

  4、虚引用(PhantomReference)

    当GC一但发现了虚引用对象,将会将PhantomReference对象插入ReferenceQueue队列,而此时PhantomReference所指向的对象并没有被GC回收,而是要等到ReferenceQueue被你真正的处理后才会被回收。虚引用的用法:

package com.asiainfo.proxydemo;

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;

public class SoftReferenceDemo {
	//软引用在JVM报告内存不足的时候才会被GC回收,否则不会回收,正是由于这种特性软引用在caching和pooling中用处广泛。软引用的用法
	public static void soft(){
		Object obj = new Object();
		ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();
		SoftReference<Object> softRef = new SoftReference<Object>(obj, refQueue);
		System.out.println(softRef.get()); // java.lang.Object@f9f9d8
		System.out.println(refQueue.poll());// null

		// 清除强引用,触发GC
		obj = null;
		System.gc();

		System.out.println(softRef.get());

		try {
			Thread.sleep(200);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(refQueue.poll());
	}
	//当GC一但发现了弱引用对象,将会释放WeakReference所引用的对象。弱引用使用方法与软引用类似,但回收策略不同。
    public static void weak(){
    	 Object obj = new Object();
    	    ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();
    	    WeakReference<Object> weakRef = new WeakReference<Object>(obj, refQueue);
    	    System.out.println(weakRef.get());
    	    System.out.println(refQueue.poll());
    	    obj = null;
    	    System.gc();
    	    System.out.println(weakRef.get());
    	    System.out.println(refQueue.poll());

    }
 // 如果obj被置为null,当GC发现了虚引用,GC会将phanRef插入进我们之前创建时传入的refQueue队列
 // 注意,此时phanRef所引用的obj对象,并没有被GC回收,在我们显式地调用refQueue.poll返回phanRef之后
 // 当GC第二次发现虚引用,而此时JVM将phanRef插入到refQueue会插入失败,此时GC才会对obj进行回收
   public static void phantom() throws InterruptedException{
	   Object obj = new Object();
	    ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();
	    PhantomReference<Object> phanRef = new PhantomReference<Object>(obj, refQueue);
	    /// 调用phanRef.get()不管在什么情况下会一直返回null
	    System.out.println(phanRef.get());
	    System.out.println(refQueue.poll());
	    obj = null;
	    System.gc();
	    System.out.println(phanRef.get());
	    System.out.println(refQueue.poll());
	    Thread.sleep(300);
	    System.out.println(refQueue.poll());
   }
	public static void main(String[] args) {
       try {
		SoftReferenceDemo.phantom();
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	}
}

弱引用与虚引用的用处

  软引用很明显可以用来制作caching和pooling,而弱引用与虚引用呢?其实用处也很大,首先我们来看看弱引用,举个例子:

class Registry {
    private Set registeredObjects = new HashSet();
 
    public void register(Object object) {
        registeredObjects.add( object );
    }
}

所有我添加进 registeredObjects 中的object永远不会被GC回收,因为这里有个强引用保存在registeredObjects里,另一方面如果我把代码改为如下:

class Registry {
     private Set registeredObjects = new HashSet();
 
     public void register(Object object) {
         registeredObjects.add( new WeakReference(object) );
     }
 }

现在如果GC想要回收registeredObjects中的object,便能够实现了,同样在使用HashMap如果想实现如上的效果,一种更好的实现是使用WeakHashMap。

而虚引用呢?我们先来看看javadoc的部分说明:

Phantom references are useful for implementing cleanup operations that are necessary before an object gets garbage-collected. They are sometimes more flexible than the finalize() method.

翻译一下:

虚引用在实现一个对象被回收之前必须做清理操作是很有用的。有时候,他们比finalize()方法更灵活。

很明显的,虚引用可以用来做对象被回收之前的清理工作

参考:http://www.cnblogs.com/newcj/archive/2011/05/15/2046882.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值