`

java.lang.ref.Reference和ReferenceQueue源码解读

 
阅读更多

Reference类是所有引用对象(包括WeakReference、SoftReference、PhantomReference等)的抽象基础类。这个类定义了所有引用对象的公共操作。因为引用对象的实现是跟垃圾收集器紧密关联的,所以这个类不应该被直接继承

 

ReferenceQueue,引用对象在合适的可达性状态(Reference指向的对象不存在任何强引用)被探测到时,由垃圾收集器将其添加到所注册的那个ReferenceQueue中

 

我想只要说清楚这两个类的设计上的两个关键点就足够了解它们了

 

1.如何实现队列

ReferenceQueue是一个先进后出(FILO)的队列,用于保存注册在这个队列的且引用的对象已经被垃圾收集器回收的引用对象。这个队列的实现其实是由这两个类的协同完成的。

ReferenceQueue类中保存一个Reference对象的属性head,用于表示队列的队顶。

每个Reference对象都有一个Reference对象的属性next,用于保存队列中下一个元素。可以看看一个Reference对象被放入ReferenceQueue时做了什么

boolean enqueue(Reference<? extends T> r) { /* Called only by Reference class */
        synchronized (lock) {
            // Check that since getting the lock this reference hasn't already been
            // enqueued (and even then removed)
            ReferenceQueue<?> queue = r.queue;
            if ((queue == NULL) || (queue == ENQUEUED)) {
                return false;
            }
            assert queue == this;
            r.queue = ENQUEUED;
//关键在这,队列的head赋值给新加入队列的Reference对象的next属性,如果队列
head为空,next就赋值为Reference对象自己。然后再把新加入对象赋值给队列的head
            r.next = (head == null) ? r : head;
            head = r;
            queueLength++;
            if (r instanceof FinalReference) {
                sun.misc.VM.addFinalRefCount(1);
            }
            lock.notifyAll();
            return true;
        }
    }

 

 

2.Reference是如何被放入队列的

Reference类有一个内部静态类ReferenceHandler extends Thread,这个内部类中有静态代码块生成该类的一个守护线程对象并启动。那这个静态内部类的run方法做了什么,有什么作用呢?

run方法代码如下

public void run() {
            while (true) {
                tryHandlePending(true);
            }
        }

 然后把tryHandlePending的关键代码贴出来

if (pending != null) {
//取出pending对象
                    r = pending;
                    // 'instanceof' might throw OutOfMemoryError sometimes
                    // so do this before un-linking 'r' from the 'pending' chain...
                    c = r instanceof Cleaner ? (Cleaner) r : null;
                    // unlink 'r' from 'pending' chain
//把pending对象的discovered属性设为pending
                    pending = r.discovered;
                    r.discovered = null;
                } else {
                    // The waiting on the lock may cause an OutOfMemoryError
                    // because it may try to allocate exception objects.
                    if (waitForNotify) {
                        lock.wait();
                    }
                    // retry if waited
                    return waitForNotify;
                }

 它的作用就是不停地从pending队列取出,并放入ReferenceQueue中。

 

这里又出现一个pending队列,它的实现也很简单。Reference类中有一个静态属性Reference pending。这个pending对象相当于pending队列的顶部,它的discovered属性则是pending队列的下一个元素,以此类推。

那又是谁把这些Reference对象放入pending队列呢?答案是垃圾收集器,它会把可达性合适的引用放入pending队列

 

那么整个过程就很明了了,一旦一个Reference引用指向的对象可达性合适,这个引用就会被垃圾收集器放到pending队列中,而同时一个辅助线程ReferenceHandler则不停地从中取出Reference对象放入到该对象注册的ReferenceQueue中

分享到:
评论

相关推荐

    深入探讨 java-lang-ref 包.docx

    总结,java.lang.ref 包中的四种引用类型——StrongReference、SoftReference、WeakReference 和 PhantomReference,提供了不同的内存管理策略,适应不同的场景需求。强引用是最常用的引用类型,但在处理大对象或...

    Java中的软引用弱引用和虚引用.docx

    import java.lang.ref.ReferenceQueue; public class PhantomReferenceDemo { public static void main(String[] args) { String str = new String("abc"); ReferenceQueue&lt;String&gt; queue = new ReferenceQueue...

    Java功底之Reference

    在Java编程语言中,`Reference`类是一个非常特殊且重要的概念,它超出了常规的引用类型,如`Object`或数组引用。`Reference`类及其子类主要用于处理对象的软引用、弱引用和虚引用,这些引用类型在内存管理,特别是...

    Java Reference源码解析

    Java Reference源码解析 Java Reference是Java语言的一种机制,用于追踪对象的可达性和垃圾回收。Java Reference源码解析主要为大家详细解析了Java Reference源码,具有一定的参考价值,感兴趣的小伙伴们可以参考...

    15个顶级Java多线程面试题及回答.docx

    ### 15个顶级Java多线程面试题详解 #### 题目一:线程执行顺序控制 **题目:** 如何确保线程T2在T1执行完毕后执行,而T3在T2执行完毕后执行? **解答:** 在Java中可以通过`Thread.join()`方法来实现线程之间的顺序...

    referenceInJava:Java强引用,软引用,弱引用以及虚引用测试项目

    软引用通过`java.lang.ref.SoftReference`类实现。 - 示例代码:`SoftReference&lt;String&gt; softRef = new SoftReference(new String("Soft Reference"));` 3. **弱引用(Weak Reference)**: - 弱引用比软引用更弱...

    Java的四种引用

    从JDK 1.2版本开始,Java引入了一种更为精细的引用类型管理机制,通过四种不同的引用类型:强引用、软引用、弱引用和虚引用,让开发者能够更加灵活地控制对象的生命周期。这种机制不仅提升了Java应用程序对内存使用...

    全面解析Java中的引用类型

    - **类表示**:通过`java.lang.ref.SoftReference`类实现。 - **用途**:常用于实现内存敏感的高速缓存,例如,当内存不足时,软引用的对象会被回收以释放内存。 - **示例**:创建一个`SoftReference`对象,当...

    浅谈Java中的四种引用方式的区别

    Java使用`java.lang.ref.SoftReference`类来表示软引用。 - 当内存空间不足时,JVM会回收软引用关联的对象,以防止`OutOfMemoryError`的发生。软引用常用于实现缓存,如网页缓存和图片缓存,以便在内存紧张时自动...

    强,软,弱,虚1

    Java通过`java.lang.ref.SoftReference`类来实现软引用。相比于强引用,软引用提供了一种在内存不足时释放资源的机制,以防止系统崩溃。因此,软引用常用于缓存策略,允许在内存允许的情况下保持缓存,而在内存紧张...

    Java对象的引用.pdf

    这些引用类型通过`java.lang.ref`包中的`SoftReference`、`WeakReference`和`PhantomReference`类实现,而`ReferenceQueue`类用于与这三种引用类型一起工作,记录引用对象被回收的信息。 以下是一个简单的例子展示...

    Java引用总结--StrongReference、SoftReference、WeakReference、PhantomRef

    Java从1.2版本开始引入了四种引用,分别是强引用(StrongReference)、软引用(SoftReference)、弱引用(WeakReference)和虚引用(PhantomReference)。这四种引用的级别由高到低依次为:强引用 &gt; 软引用 &gt; 弱引用...

    java 引用相关文档

    在这里,我们将详细讲解Java中的四种引用类型:强引用、软引用、弱引用和虚引用,以及它们在内存管理和垃圾收集中的作用。 1. **强引用(Strong Reference)** - 强引用是Java中最常见的引用类型,它是默认的引用...

    Java引用类型1

    Java提供了四种不同级别的引用类型:强引用、软引用、弱引用和虚引用(幻象引用),每种引用类型在内存管理中有不同的作用。 1. **强引用(Strong Reference)** - 强引用是最常见的引用类型,即通常的变量赋值。...

    Java中弱引用软引用虚引用及强引用的区别Java开发Ja

    在Java开发中,熟练掌握这些引用类型的概念和使用场景,可以帮助我们编写出更加高效、健壮的代码。同时,理解垃圾收集的工作原理也非常重要,因为这直接影响到程序的性能和稳定性。在实际开发中,合理利用这些引用...

    java9源码下载-Java:java练习

    StackOverflowError:Fibonacci.java GC(垃圾回收练习) ReferenceQueue finlize()-- java9已弃用 reflect(反射) 反射实例:ReflectSample.java 实现自己的类加载器:MyClassLoader.java 类加载测试:...

    详解Java对象的强、软、弱和虚引用+ReferenceQueue

    Java对象的强、软、弱和虚引用+ReferenceQueue Java对象的强、软、弱和虚引用是Java语言中的一种机制,用于控制对象的生命周期和垃圾回收。下面是对Java对象的强、软、弱和虚引用的详细解释: 一、强引用(Strong...

    Java 引用1

    在`java.lang.ref`包中,有三个类分别对应这四种引用:`SoftReference`、`WeakReference`和`PhantomReference`。此外,`ReferenceQueue`用于存储被回收引用的实例,以便开发者可以监控对象的回收状态。 在实际应用...

    smartref:Java 1.5+ 的简单引用类型和容器

    这些智能引用类型配合相应的容器类,如`java.lang.ref.ReferenceQueue`和`java.util.WeakHashMap`,可以在特定场景下实现高效和灵活的对象管理。例如,`WeakHashMap`中的键使用弱引用,当键的对象被垃圾收集时,键值...

Global site tag (gtag.js) - Google Analytics