Java 引用队列的含义

Java 引用队列的含义,java,garbage-collection,weak-references,phantom-reference,Java,Garbage Collection,Weak References,Phantom Reference,我试图理解classReferenceQueue 它是的可选构造函数参数 SoftReference 及 它也是PhantomReference的必需参数 根据我读到的信息,我可以写一些论文 a) 对于PhantomReference方法,get始终返回null (b) 对于幻影参考: 1.gc检测到可以从内存中删除对象 2.对放入引用队列的对象的引用 当我们从队列调用clear或link-to-reference时,因为无法访问而gc看到 3.finalize方法调用 4.可用内存 对于弱/

我试图理解class
ReferenceQueue

它是的可选构造函数参数

SoftReference

它也是
PhantomReference
的必需参数

根据我读到的信息,我可以写一些论文

a) 对于PhantomReference方法,get始终返回null

(b) 对于幻影参考:
1.gc检测到可以从内存中删除对象
2.对放入引用队列的对象的引用
当我们从队列调用clear或link-to-reference时,因为无法访问而gc看到 3.finalize方法调用
4.可用内存
对于弱/软引用:
1.gc检测到可以从内存中删除对象
2.finalize方法调用
3.可用内存
4.对放入队列的对象的引用

  • 何时可以将第二个参数传递给
    XXXReference
    构造函数
  • 我能得到什么帮助
  • 为什么
    PhantomReference
    没有没有
    ReferenceQueue
    的构造函数
  • 有ReferenceQuee的get方法总是返回null的原因是什么
  • 1) 何时可以将第二个参数传递给XXXReference构造函数

    你想什么时候做就什么时候做。当引用被破坏时,只要需要处理它们,就应该这样做

    2) 我能得到什么帮助

    我不明白这个问题

    3) 为什么PhantomReference没有无ReferenceQueue的构造函数

    PhantomReference
    的目的是成为常规定稿的更灵活的替代方案。但是,为了使其工作,必须将引用排入队列,以使最终完成替换代码工作。(无法处理未排队的
    PhantomReference

    相比之下,
    SoftReference
    WeakReference
    对象通常在不排队的情况下很有用

    4) 让ReferenceQueue的get方法总是返回null的原因是什么

    ReferenceQueue
    API没有
    get()
    方法,所以我猜您是在谈论
    PhantomReference
    API。之所以有
    get()
    方法是为了与超类兼容。将
    get()
    定义为返回
    null
    的原因如下:

    为了确保可回收对象保持这种状态,可能无法检索幻像引用的referent:幻像引用的get方法始终返回null

    (见附件。)

    换句话说,这样做是为了使所指对象不可能“复活”

    更新

    事实上,所有
    Reference
    类将在将
    Reference
    排队之前清除referent。(实际上,GC本身直接执行此操作。)从
    ReferenceQueue
    提取引用的应用程序代码不能使用
    get()
    方法来标识(现在已删除!)引用对象。他们必须以另一种方式去做;e、 g.基于参考对象的标识

    幻影引用的区别在于
    get()
    方法总是返回
    null
    。(所以javadoc中的解释……不令人信服。)

    1) 何时可以将第二个参数传递给XXXReference构造函数

    你想什么时候做就什么时候做。当引用被破坏时,只要需要处理它们,就应该这样做

    2) 我能得到什么帮助

    我不明白这个问题

    3) 为什么PhantomReference没有无ReferenceQueue的构造函数

    PhantomReference
    的目的是成为常规定稿的更灵活的替代方案。但是,为了使其工作,必须将引用排入队列,以使最终完成替换代码工作。(无法处理未排队的
    PhantomReference

    相比之下,
    SoftReference
    WeakReference
    对象通常在不排队的情况下很有用

    4) 让ReferenceQueue的get方法总是返回null的原因是什么

    ReferenceQueue
    API没有
    get()
    方法,所以我猜您是在谈论
    PhantomReference
    API。之所以有
    get()
    方法是为了与超类兼容。将
    get()
    定义为返回
    null
    的原因如下:

    为了确保可回收对象保持这种状态,可能无法检索幻像引用的referent:幻像引用的get方法始终返回null

    (见附件。)

    换句话说,这样做是为了使所指对象不可能“复活”

    更新

    事实上,所有
    Reference
    类将在将
    Reference
    排队之前清除referent。(实际上,GC本身直接执行此操作。)从
    ReferenceQueue
    提取引用的应用程序代码不能使用
    get()
    方法来标识(现在已删除!)引用对象。他们必须以另一种方式去做;e、 g.基于参考对象的标识


    幻影引用的区别在于
    get()
    方法总是返回
    null
    。(所以javadoc中的解释……不太令人信服。)

    也许,下面的程序有点帮助:

    public class SimpleGCExample {
        public static void main(String[] args) throws InterruptedException {
            ReferenceQueue<Object> queue=new ReferenceQueue<>();
            SimpleGCExample e = new SimpleGCExample();
            Reference<Object> pRef=new PhantomReference<>(e, queue),
                              wRef=new WeakReference<>(e, queue);
            e = null;
            for(int count=0, collected=0; collected<2; ) {
                Reference ref=queue.remove(100);
                if(ref==null) {
                    System.gc();
                    count++;
                }
                else {
                    collected++;
                    System.out.println((ref==wRef? "weak": "phantom")
                                      +" reference enqueued after "+count+" gc polls");
                }
            }
        }
    
        @Override
        protected void finalize() throws Throwable {
            System.out.println("finalizing the object in "+Thread.currentThread());
            Thread.sleep(100);
            System.out.println("done finalizing.");
        }
    }
    

    在线程中终结对象[终结器,8,系统]
    弱引用在1次gc轮询后排队
    完成定稿。
    幻象引用在2次gc轮询后排队
    
    由于多线程,前两条消息的顺序有时会有所不同。有时,幻影引用报告在三次轮询后进入队列,这表明它花费的时间超过了指定的100毫秒

    关键是

    • 软引用和弱引用被清除
      public class SimpleGCExample {
          public static void main(String[] args) throws InterruptedException {
              ReferenceQueue<Object> queue=new ReferenceQueue<>();
              SimpleGCExample e = new SimpleGCExample();
              Reference<Object> pRef=new PhantomReference<>(e, queue),
                                wRef=new WeakReference<>(e, queue);
              e = null;
              for(int count=0, collected=0; collected<2; ) {
                  Reference ref=queue.remove(100);
                  if(ref==null) {
                      System.gc();
                      count++;
                  }
                  else {
                      collected++;
                      System.out.println((ref==wRef? "weak": "phantom")
                                        +" reference enqueued after "+count+" gc polls");
                  }
              }
          }
      
          @Override
          protected void finalize() throws Throwable {
              System.out.println("finalizing the object in "+Thread.currentThread());
              Thread.sleep(100);
              System.out.println("done finalizing.");
          }
      }