您的位置:首页 > 编程语言 > Java开发

学习整理——Java四种引用类型

2016-09-13 10:17 363 查看
参考:http://www.pocketcn.com/forum-viewthread-tid-1661-fromuid-1477.html

从jdk1.2开始,Java把对象引用分为四个等级——强引用、软引用、弱引用、虚引用,每一种引用都有其应用的地方,提供高度灵活性给程序。

强引用

实际程序当中,强引用是使用最普遍的。一个对象拥有强引用,垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题,保证后续程序的正确性。

通过声明一个引用变量并指定它所引用的对象的方式就是强引用:A a1 = new A(); A a2 = a1;

import java.util.*;

public class ReferenceTest {
public static void main(String[] args){
Test test = new Test();
test = null;
try {
System.gc();
Thread.sleep(10000);
} catch (Exception e) {
e.printStackTrace();
}
}
}

class Test {
public Test(){
System.out.println("Created at " + System.currentTimeMillis());
}

@Override
public void finalize(){
System.out.println("Instance is destroyed by system at " + System.currentTimeMillis());
}
}程序使用强引用引用一个对象,然后将变量置为null,向系统请求gc。由于对象没有任何引用,一旦执行gc,该对象将被回收。
输出

Created at 1473734462128
Instance is destroyed by system at 1473734462160

软引用

如果一个对象只具有(如果还具有强引用则不在此讨论范围)软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。也就是说,软引用为那些失去了强引用的对象提供一个相对安全的保障,只有内存空间充足,这些对象可以继续存在。由此可见,软引用可以用于一些缓存的应用环境当中。

使用软引用使用SoftReference;

SoftReference<T> softRefernce = new SoftReference<T>(t);   // 将对象引用赋值给一个软引用

T t1 = (T) softReference.get();  // 返回一个强引用,若对象因内存告急被回收,则返回null 

软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。 由于软引用对象也是对象,当它所软引用的对象被回收之后,该软引用失去了存在性,该软引用对象应当也被处理掉。

ReferenceQueue queue = new ReferenceQueue();   // 软引用队列

SoftReference ref = new SoftReference(aMyObject, queue);   //  将队列的引用加入到软引用对象的构造函数参数中

// 处理没有存在性的软引用对象

SofeReference softReference = null;

while((softReference = queue.poll())!=null){

   //  此时在该队列里面的软引用对象所引用的对象已被gc回收 

   //  相应操作

}

在上面代码的基础上加入软引用

<span style="white-space:pre"> </span>public static void main(String[] args){
Test test = new Test();
SoftReference<Test> softReference = new SoftReference<Test>(test); // 将对象加入软引用
test = null;
try {
System.gc();
Thread.sleep(10000);
} catch (Exception e) {
e.printStackTrace();
}
}输出
Created at 1473736268577

弱引用

弱引用与软引用类似,主要区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。使用弱引用,可以让对象在不添加新的强引用(添加强引用会阻碍正常gc)的情况下在某些地方能够返回出它的引用,可以像正常流程一样被系统管理。如WeakHashMap,value何map之间是一种很弱的关系,当value在外部不再存在时,map便不能把它找到。

弱引用使用WeakReference,用法与SoftReference类似。

弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。

将上述代码的软引用改为弱引用

public static void main(String[] args){
Test test = new Test();
//SoftReference<Test> softReference = new SoftReference<Test>(test); // 将对象加入软引用
WeakReference<Test> weakReference = new WeakReference<Test>(test); // 将对象加入弱引用
test = null;
try {
System.gc();
Thread.sleep(10000);
} catch (Exception e) {
e.printStackTrace();
}
}

输出
Created at 1473737483154
Instance is destroyed by system at 1473737483169

虚引用

虚引用,顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。
虚引用主要用来跟踪对象被垃圾回收器回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列 (ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之 关联的引用队列中。

有意思的是,PhantomReference 源码中显示了get()方法永远返回null

public class PhantomReference<T> extends Reference<T> {

/**
* Returns this reference object's referent. Because the referent of a
* phantom reference is always inaccessible, this method always returns
* <code>null</code>.
*
* @return <code>null</code>
*/
public T get() {
return null;
}

/**
* Creates a new phantom reference that refers to the given object and
* is registered with the given queue.
*
* <p> It is possible to create a phantom reference with a <tt>null</tt>
* queue, but such a reference is completely useless: Its <tt>get</tt>
* method will always return null and, since it does not have a queue, it
* will never be enqueued.
*
* @param referent the object the new phantom reference will refer to
* @param q the queue with which the reference is to be registered,
* or <tt>null</tt> if registration is not required
*/
public PhantomReference(T referent, ReferenceQueue<? super T> q) {
super(referent, q);
}

}所以主要还是用于跟踪对象被回收情况。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: