今天 4ye 来和小伙伴们聊聊这个 强引用软引用弱引用幻象引用虚引用)啦

嘿嘿,主要是最近读源码的时候经常看到,然后又想到自己第一次知道这个神奇的东西是在 2020-8-21

为啥记得这么清楚呢? 主要是翻到了 杨晓峰大佬的 pdf 哈哈

这次我一定得记牢不搞混了 哈哈,一起来看看叭

文章概览

一.  四种引用的概念

二.  对象可达性介绍

三.  Springboot源码中的引用

概念介绍

不同的引用类型,主要体现的是对象不同的可达性(reachable)状态和对垃圾收集的影响

01.  强引用

这个就是我们创建的普通对象了~ 当该对象被显示地赋值为 null 时,或者没有被其他存活的对象继续引用时,它就会成为垃圾收集器的目标,等待被收回

02.  软引用

软引用( SoftReference ) , 当内存不足 时会被回收

比如

被回收后,这里会打印 null 而不是 Java4ye

03.  弱引用

弱引用( WeakReference ) , 当 垃圾回收器 进行垃圾回收时,无论内存足与否,它都会被垃圾回收器回收

比如

被回收后,这里也是会打印 null 而不是 Java4ye

04.  虚引用

虚引用( ReferenceQueue ) , 这个也是随时会被回收,不过它的作用更像一个标记,当对象被回收时,它不为 null ,但是要注意,无论什么时候去调用 虚引用的 get 方法,都只能获取到一个 null 值。

为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知 —— <<深入理解Java虚拟机>>

这里引用 http://www.javashuo.com/article/p-zyvdcbhl-nb.html 该文章的例子

User user = new User(1, "Java4ye");
ReferenceQueue<User> userReferenceQueue = new ReferenceQueue<>();
// 创建User对象的虚引用
PhantomReference<User> phantomReference = new PhantomReference<>(user, userReferenceQueue);
// 去掉强引用
user = null;
System.out.println(phantomReference.get());
// 手动触发GC
System.gc();
System.out.println("GC: " + phantomReference.get());
Reference<? extends User> reference = null;
try {
reference = userReferenceQueue.remove(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (reference != null) {
System.out.println("对象User被回收了:");
}

对象可达性

那么 简单介绍完上面的 4 种引用后,我们再来看看它的可达性~

如图~

  1. 强可达: 比如 创建一个对象时,创建它的线程对该对象就是强可达
  2. 软可达: 只能通过软引用访问
  3. 弱可达: 只能通过弱引用访问
  4. 虚可达: 当对象没有 强,软,弱 引用关联时,并且 finalize 过,就会进入该状态
  5. 不可达: 意味着该对象可以被清除了。

通过最开始的代码例子和上面的图(双向箭头)我们还可以发现,软引用和弱引用和强引用这三者间可以进行转换( 通过 Referenceget() 可获取到原对象),这意味着:

对于软引用、弱引用之类,垃圾收集器可能会存在二次确认的问题,以保证处于弱引用状态的对象,没有改变为强引用。

JDK8 中,还可以通过 指定参数打印引用的相关信息

-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintReferenceGC

JDK8 中使用 ParrallelGC 收集的垃圾回收日志 (大佬 pdf 中的例子)

0.403: [GC (Allocation Failure) 0.871: [SoftReference, 0 refs, 0.0000393 secs]0.871: [WeakReference, 8 refs, 0.0000138 secs]0.871: [FinalReference, 4 refs, 0.0000094 secs]0.871:

[PhantomReference, 0 refs, 0 refs, 0.0000085 secs]0.871: [JNI Weak Reference, 0.0000071 secs][PSYoungGen: 76272K->10720K(141824K)] 128286K->128422K(316928K), 0.4683919 secs] [Times:

user=1.17 sys=0.03, real=0.47 secs]

再记录下这个点(哈哈 不知道啥时候才会用上~)

通过底层API来达到强引用

Springboot源码中的使用

嘿嘿 终于来到重点了 ,正如开头提到的~ 4ye 也是在 Springboot 源码中看到这个

ConcurrentReferenceHashMap 才想起要写一下这篇文章滴✍

那么这个 ConcurrentReferenceHashMap 到底有什么作用呢?

ConcurrentReferenceHashMap 能指定所存放对象的引用级别

默认情况下是 软引用级别

比如 在 Springboot自动装配原理探索 一文中提到的 Springboot SPI 机制 其中的主角: SpringFactoriesLoader

源码如下:

还有自动配置过程中的注解扫描 AnnotationsScanner

以及在 万字长文,带你快速上手这些池化技术! 一文中出现的 异步任务线程池ThreadPoolTaskExecutor

源码如下: (可以看到这里指明了是 弱引用级别

总结

  1. 看完上面的例子,觉得可以模仿下 SpringbootConcurrentReferenceHashMap ,对对象进行一个合理的存储,间接地优化jvm ,提高垃圾回收的效率。
  2. 这两个别搞混了: 软引用,内存不足时回收弱引用,在进行垃圾回收时,不管内存足与否,都会被回收,

最后

欢迎小伙伴们来一起探讨问题~

如果你觉得本篇文章还不错的话,那拜托再点点赞支持一下呀

让我们开始这一场意外的相遇吧!~

欢迎留言!谢谢支持!ヾ(≧▽≦*)o 冲冲冲!!

我是4ye 咱们下期应该……很快再见!!

四种引用类型在Springboot中的使用的更多相关文章

  1. java中四种引用类型

    java中四种引用类型  今天看代码,里面有一个类java.lang.ref.SoftReference把小弟弄神了,试想一下,接触java已经有3年了哇,连lang包下面的类都不了解,怎么混.后来在 ...

  2. java中四种引用类型(对象的强、软、弱和虚引用)

    对象的强.软.弱和虚引用在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使用它.从JDK 1.2 ...

  3. Java中的四种引用类型比较

    1.引用的概念 引用这个概念是与JAVA虚拟机的垃圾回收有关的,不同的引用类型对应不同的垃圾回收策略或时机. 垃圾收集可能是大家感到难于理解的较难的概念之一,因为它并不能总是毫无遗漏地解决Java运行 ...

  4. Java魔法堂:四种引用类型、ReferenceQueue和WeakHashMap

    一.前言 JDK1.2以前只提供一种引用类型——强引用 Object obj = new Object(); .而JDK1.2后我们多另外的三个选择分别是软引用 java.lang.ref.SoftR ...

  5. 你知道Java的四种引用类型吗

    关于java四种引用类型,我也是刚了解,特此记下! 在Java中提供了四个级别的引用:强引用,软引用,弱引用和虚引用.在这四个引用类型中,只有强引用FinalReference类是包内可见,其他三种引 ...

  6. Java的四种引用类型之弱引用

    先说结论: 首先,Java中有四种引用类型:强引用.软引用.弱引用.虚引用.-- 在 Java 1.2 中添加的,见 package java.lang.ref; . 其次,这几个概念是与垃圾回收有关 ...

  7. java基础之 数据类型 & 值传递 引用传递 & String & 四种引用类型

    一.Java数据类型 分为基本数据类型与引用数据类型 基本数据类型: byte:Java中最小的数据类型,在内存中占1个字节(8 bit),取值范围-128~127,默认值0 short:短整型,2个 ...

  8. java四种引用类型以及使用场景详解

    每种编程语言都有自己操作内存中元素的方式,例如在 C 和 C++ 里是通过指针,而在 Java 中则是通过“引用”.在 Java 中一切都被视为了对象,但是我们操作的标识符实际上是对象的一个引用(re ...

  9. Java 中的四种引用类型(转)

    目录 背景 简介          1. 强引用 StrongReference          2. 弱引用 WeakReference          3. 软引用 SoftReference ...

随机推荐

  1. (5)air202读取串口数据并上传到阿里云显示

    一.首先进行云端设置 根据串口助手显示的信息,以及模块文档说明我们可以知道 其中red和ir是红光LED的原始数据, HR表示心率值, HRvalid是心率是否有效标识, SP02是血氧数值,,SPO ...

  2. python常用工具库介绍

    Numpy:科学计算 HOME:  http://www.numpy.org/ NumPy is the fundamental package for scientific computing wi ...

  3. Ubuntu 16.04 + python3 源码 安装+使用labelImg最新版

    安装 sudo apt-get update sudo apt-get upgrade sudo apt install python3-pip git clone https://github.co ...

  4. java对象的引用级别

    解释 在java中也有引用的概念,其实就可以认为是变量.标题中的引用级别是指变量与对象之前的引用级别.java中分为4种,按引用强弱关系排序分别是:强引用.软引用.弱引用.虚引用. 强引用(Stron ...

  5. 如何实现CSS限制字数,超出部份显示省略号

    <div style="width:200px; white-space:nowrap;overflow:hidden;text-overflow:ellipsis; border:1 ...

  6. 利用Struts2拦截器完成文件上传功能

    Struts2的图片上传以及页面展示图片 在上次的CRUD基础上加上图片上传功能 (https://www.cnblogs.com/liuwenwu9527/p/11108611.html) 文件上传 ...

  7. 板子题 Sol

    RT Cyber_Tree 出了一道板子题... 这题乍看之下貌似还不戳,但如果您做过类似的题,那么这就是一道板子题.... 首先明确要求的是什么,如果我们只考虑权值最大而不考虑最小距离,那么要求的显 ...

  8. 将两个byte型拼接成16位二进制,再转化为十进制

    short s = 0; //一个16位整形变量,初值为 0000 0000 0000 0000 byte b1 = 1; //一个byte的变量,作为转换后的高8位,假设初值为 0000 0001 ...

  9. JS020. Array map()函数查到需要的元素时跳出遍历循环,不再执行到数组边界

    Array.prototype.map() map( )  方法创建一个 新数组 *,其结果是该数组中的每个元素是调用一次提供的 函数后的返回值 *.[ MDN / RUNOOB ] * map 添加 ...

  10. Input 只能输入数字,数字和字母等的正则表达式

    JS只能输入数字,数字和字母等的正则表达式 1.文本框只能输入数字代码(小数点也不能输入) <input onkeyup="this.value=this.value.replace( ...