Java对象的强、软、弱和虚引用

欢迎进入Java社区论坛,与200万技术人员互动交流 >>进入

在图11-10中,带实线的箭头表示强引用,带虚线的箭头表示弱引用。从图中可以看出,此时”hello”对象被str强引用,并且被一个WeakReference对象弱引用,因此”hello”对象不会被垃圾回收。在以下程序代码中,把引用”hello”对象的str变量置为null,然后再通过WeakReference弱引用的get()方法获得”hello”对象的引用:

String str = new String(“hello”); //① ReferenceQueue<String> rq = new ReferenceQueue<String>(); //② WeakReference<String> wf = new WeakReference<String>(str, rq); //③

str=null; //④取消”hello”对象的强引用String str1=wf.get(); //⑤假如”hello”对象没有被回收,str1引用”hello”对象

//假如”hello”对象没有被回收,rq.poll()返回nullReference<? extends String> ref=rq.poll(); //⑥

执行完以上第④行后,内存中引用与对象的关系如图11-11所示,此 时”hello”对象仅仅具有弱引用,因此它有可能被垃圾回收。假如它还没有被垃圾回收,那么接下来在第⑤行执行wf.get()方法会返回 “hello”对象的引用,并且使得这个对象被str1强引用。再接下来在第⑥行执行rq.poll()方法会返回null,因为此时引用队列中没有任何 引用。ReferenceQueue的poll()方法用于返回队列中的引用,如果没有则返回null。

图11-11 “hello”对象只具有弱引用

在以下程序代码中,执行完第④行后,”hello”对象仅仅具有弱引用。接下来两次调用System.gc()方法,催促垃圾回收器工作,从而提高 “hello”对象被回收的可能性。假如”hello”对象被回收,那么WeakReference对象的引用被加入到ReferenceQueue中, 接下来wf.get()方法返回null,并且rq.poll()方法返回WeakReference对象的引用。图11-12显示了执行完第⑧行后内存 中引用与对象的关系。

String str = new String(“hello”); //①ReferenceQueue<String> rq = new ReferenceQueue<String>(); //② WeakReference<String> wf = new WeakReference<String>(str, rq); //③str=null; //④

//两次催促垃圾回收器工作,提高”hello”对象被回收的可能性System.gc(); //⑤System.gc(); //⑥String str1=wf.get(); //⑦ 假如”hello”对象被回收,str1为nullReference<? extends String> ref=rq.poll(); //⑧

图11-12 “hello”对象被垃圾回收,弱引用被加入到引用队列

在以下例程11-15的References类中,依次创建了10个软引用、10个弱引用和10个虚引用,它们各自引用一个Grocery对象。从程序运 行时的打印结果可以看出,虚引用形同虚设,它所引用的对象随时可能被垃圾回收,具有弱引用的对象拥有稍微长的生命周期,当垃圾回收器执行回收操作时,有可 能被垃圾回收,具有软引用的对象拥有较长的生命周期,但在Java虚拟机认为内存不足的情况下,也会被垃圾回收。

例程11-15 References.javaimport java.lang.ref.*;import java.util.*;

class Grocery{private static final int SIZE = 10000;//属性d使得每个Grocery对象占用较多内存,有80K左右private double[] d = new double[SIZE]; private String id;public Grocery(String id) { this.id = id; }public String toString() { return id; }public void finalize() {System.out.println(“Finalizing ” + id);}}

public class References {private static ReferenceQueue<Grocery> rq = new ReferenceQueue<Grocery>();public static void checkQueue() {Reference<? extends Grocery> inq = rq.poll(); //从队列中取出一个引用if(inq != null)System.out.println(“In queue: “+inq+” : “+inq.get());}

public static void main(String[] args) {final int size=10;//创建10个Grocery对象以及10个软引用Set<SoftReference<Grocery>> sa = new HashSet<SoftReference<Grocery>>();for(int i = 0; i < size; i++) {SoftReference<Grocery> ref=new SoftReference<Grocery>(new Grocery(“Soft ” + i), rq);System.out.println(“Just created: ” +ref.get());sa.add(ref);}System.gc();checkQueue();

//创建10个Grocery对象以及10个弱引用Set<WeakReference<Grocery>> wa = new HashSet<WeakReference<Grocery>>();for(int i = 0; i < size; i++) {WeakReference<Grocery> ref=new WeakReference<Grocery>(new Grocery(“Weak ” + i), rq);System.out.println(“Just created: ” +ref.get());wa.add(ref); }System.gc();checkQueue();

//创建10个Grocery对象以及10个虚引用Set<PhantomReference<Grocery>> pa = new HashSet<PhantomReference<Grocery>>();for(int i = 0; i < size; i++) {PhantomReference<Grocery>ref = new PhantomReference<Grocery>(new Grocery(“Phantom ” + i), rq);System.out.println(“Just created: ” +ref.get());pa.add(ref);}System.gc();checkQueue();}}

[1][2][3]

于是渐渐开始有些伤怀。

Java对象的强、软、弱和虚引用

相关文章:

你感兴趣的文章:

标签云: