Java reference

209 阅读1分钟

三种 reference类

在jvm中,如果有引用指向该对象,则该对象是可获得的(reachable),意味着你在栈中有一个普通的引用指向该对象。GC无法回收这种对象。如果你想使用一个对象,同时希望在内存不够时候,gc可以回收该对象。解决方案就是引用对象,java.lang.ref:

  • WeakReference(实现规范映射,只要gc就开始回收。有WeakHashMap的应用)
        Person p1=new Person();
        //1.创建可选的队列,可以在gc回收该对象后,放到该队列。
        ReferenceQueue<Person> refQueue = new ReferenceQueue<Person>();
        //2.创建WeakReference对象,参数实际对象+队列
        WeakReference wr=new WeakReference(p1,refQueue);
        //获取对象的方式,
        System.out.println(wr.get());
        System.out.println(refQueue.poll());
        p1=null;
        //gc之后对象被回收了,进入到了队列了。
        System.gc();
        System.out.println("after gc()");
        System.out.println(wr.get());
        System.out.println(refQueue.poll());
        
        运行结果:
        thinkinginstring.Person@6e0be858
        null
        after gc()
        null
        java.lang.ref.WeakReference@61bbe9ba
  • PhantomReference(用以调度回收前的清理工作,比finalize更灵活)
        Person p1=new Person();
        ReferenceQueue<Person> refQueue = new ReferenceQueue<Person>();
        PhantomReference pr=new PhantomReference(p1,refQueue);
        System.out.println(pr.get());
        System.out.println(refQueue.poll());
        p1=null;
        System.gc();
        System.out.println(pr.get());
        System.out.println(refQueue.poll());
        
        运行结果:
        null
        null
        null
        java.lang.ref.PhantomReference@6e0be858

Once the garbage collector decides that an object obj is phantom-reachable, it is being enqueued on the corresponding queue, but its referent is not cleared. That is, the reference queue of the phantom reference must explicitly be processed by some application code. 一旦GC决定一个“obj”是虚可达的,它(指PhantomReference)将会被入队到对应的队列,但是它的指代并没有被清除。也就是说,虚引用的引用队列一定要明确地被一些应用程序代码所处理。

  • SoftReference(内存不足时才开始回收,内存敏感的高速缓存)