java Reference 引用学习总结(1)

if (r instanceof FinalReference) {

sun.misc.VM.addFinalRefCount(1);

}

lock.notifyAll();

return true;

}

}

}

  • Enqueue

进入队列中的Reference 中的 next 为队列中一个引用,或等于this(表示当前引用为最后一个), queue = ReferenceQueue.ENQUEUE。

  • InActive

queue = ReferenceQueue.NULL; next = this

JAVA 四种引用的理解就到这了,其实 JAVA 中还有一种引用,java.lang.ref.FinalReference 应用,不过修饰符是 default, 包访问权限,主要用于 finalizer方法的执行,请关注下一篇博文。

再统一聊聊 java 引用中涉及到的引用的几个队列。

Reference中涉及到的队列(链表)

Reference next;

private static Reference pending = null;

private ReferenceQueue queue;

每个引用可以关联一个引用队列,该引用队列由应用程序创建的,,然后垃圾回收器在检测到引用不可达时,将该引用加入到该队列,应用程序可以根据该引用队列来做些处理。(也就是该引用队列 成为 垃圾回收器与应用程序的通信机制)。

ReferenceQueue 自身的结构

private volatile Reference<? extends T> head = null;

首先,应用程序如下使用引用:

public class TestReference {

private static ReferenceQueue aQueue = new ReferenceQueue();

public static void main(String args) {

Object a = new Object();   // 代码1

WeakReference ref = new WeakReference( a, aQueue );

}

}

然后在程序运行过程,内存不断消耗,直至触发垃圾回收操作。此时,垃圾收集器发现 代码1处的 a 所指向的对象,只有 ref引用它,从根路径不可达,故垃圾回收器,会将 ref 引用加入到  static Reference pending 链表中。【注意,此代码是写在JVM实现中的】

所处理的操作无非就是【 1、如果pending 为空,则将当前引用(ref) 设置为pengding,并且将 ref对象的next指针指向自己; 如果pending不为空,则将当前的引用(ref)的next指向pengding,然后pengding = 当前的引用ref                   】,所以 pengding 其实就是 一个后进新出的链表单向链表结构。

  • 由此总结出  ref 与 pengding链表关联的第一步  由JVM垃圾回收器完成。

从pengding 链表中取出引用,进行入队操作。该操作由专门的线程(ReferenceHandle 线程处理),我重点将 ReferenceHandle线程的源代码贴出已供分析。

private static class ReferenceHandler extends Thread {

ReferenceHandler(ThreadGroup g, String name) {

super(g, name);

}

public void run() {

for (;😉 {

Reference r;

synchronized (lock) {

if (pending != null) {        // 如果pengding不为空,则取出pengding 的第一个引用,然后重新设置pengding 的值(为原来的pending.next,见如下代码   a,b,c)

r = pending;                // a 将pending取出,准备入队操作

Reference rn = r.next;  // b 先获取原先pending 的 next

pending = (rn == r) ? null : rn;  // c  如果pending的next等于本身,则设在pending为空,否则为链表的下一个。//  从这里更加看出 pending 是后进先出队列。

r.next = r;

} else { // 如果 pending 为空,则线程阻塞,等待垃圾回收器添加新的引用到 pending链表中

try {

lock.wait();

} catch (InterruptedException x) { }

continue;

}

}

// Fast path for cleaners

if (r instanceof Cleaner) {

((Cleaner)r).clean();

continue;

}

ReferenceQueue q = r.queue;

if (q != ReferenceQueue.NULL) q.enqueue®;

}

}

}

参考了如下几篇非常优秀的博文,再次表示感谢:

http://hongjiang.info/java-referencequeue/

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
存中…(img-f1QnFG2k-1715700573623)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值