四种引用类型在JAVA Springboot中的使用详解

目录
  • 概念介绍
    • 01.  强引用
    • 02.  软引用
    • 03.  弱引用
    • 04.  虚引用
  • 对象可达性
  • 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 种引用后,我们再来看看它的可达性~

如图~

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

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

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

在 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

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

总结

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

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • 简述Java中的四种引用类型

    简介 从JDK1.2版本开始,把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期.这四种级别由高到低依次为:强引用.软引用.弱引用和虚引用,下面分别介绍下这四种引用. 强引用 强引用是最常用的引用类型,如下所示,new Object()会创建一个Object对象并存储在堆上,变量object存储对该对象的强引用. Object object = new Object(); 强引用不会被垃圾回收,所以要想回收该对象,则应该将指向该对象的变量显示设为null,这样该对象就由强引用转变

  • Java的四种引用方式

    目录 1.强引用(StrongReference) 2.软引用(SoftReference) 3.弱引用(WeakReference) 4.虚引用(PhantomReference) 5. 引用队列(ReferenceQueue) 1.强引用(StrongReference) 使用最普遍的引用. 只要引用链没有断开,强引用就不会断开.- 当内存空间不足,抛出OutOfMemoryError终止程序也不会回收具有强引用的对象. 通过将对象设置为null来弱化引用,使其被回收 Object obje

  • Java中四种引用详解

    目录 强引用 软引用 弱引用 虚引用 总结 java 中的 4 种引用方式,适用于不同的场景,重点需要理解虚引用,结合文字和代码 强引用 被强引用的对象,不会被垃圾回收器回收,JVM 宁愿抛出 OOM 也不会去回收被强引用的对象: M m = new M(); 软引用 当堆空间够用时,GC 不会对软引用的对象进行回收,当堆空间不足以分配新的空间时,触发 GC 就会对这部分对象进行回收,通常用在缓存等领域.将缓存对象使用软引用,空间不足的时候释放这部分空间,需要再次使用的时候,重新从 DB 中加载

  • 详解Java的引用类型及使用场景

    每种编程语言都有自己操作内存中元素的方式,例如在 C 和 C++ 里是通过指针,而在 Java 中则是通过"引用".在 JDK.1.2 之后,Java 对引用的概念进行了扩充,将引用分为了:强引用(Strong Reference).软引用(Soft Reference).弱引用(Weak Reference).虚引用(Phantom Reference)4 种,这 4 种引用的强度依次减弱,今天这篇文章就简单介绍一下这四种类型,并简单说一下他们的使用场景. 1. 强引用(Strong

  • 面试官:详细谈谈Java对象的4种引用方式

    前言 我们知道在Java中除了基础的数据类型以外,其它的都为引用类型. 而Java根据其生命周期的长短将引用类型又分为强引用.软引用.弱引用.幻象引用 . 正常情况下我们平时基本上我们只用到强引用类型,而其他的引用类型我们也就在面试中,或者平日阅读类库或其他框架源码的时候才能见到. 1.强引用 我们平日里面的用到的new了一个对象就是强引用,例如 Object obj = new Object();当JVM的内存空间不足时,宁愿抛出OutOfMemoryError使得程序异常终止也不愿意回收具有

  • 四种引用类型在JAVA Springboot中的使用详解

    目录 概念介绍 01.  强引用 02.  软引用 03.  弱引用 04.  虚引用 对象可达性 Springboot源码中的使用 总结 概念介绍 不同的引用类型,主要体现的是对象不同的可达性(reachable)状态和对垃圾收集的影响. 01.  强引用 这个就是我们创建的普通对象了~ 当该对象被显示地赋值为 null 时,或者没有被其他存活的对象继续引用时,它就会成为垃圾收集器的目标,等待被收回 02.  软引用 软引用( SoftReference ) , 当内存不足 时会被回收 比如

  • 四种引用类型在JAVA Springboot中的使用详解

    目录 概念介绍 01.  强引用 02.  软引用 03.  弱引用 04.  虚引用 对象可达性 Springboot源码中的使用 总结 概念介绍 不同的引用类型,主要体现的是对象不同的可达性(reachable)状态和对垃圾收集的影响. 01.  强引用 这个就是我们创建的普通对象了~ 当该对象被显示地赋值为 null 时,或者没有被其他存活的对象继续引用时,它就会成为垃圾收集器的目标,等待被收回 02.  软引用 软引用( SoftReference ) , 当内存不足 时会被回收 比如

  • jQuery+CSS3实现四种应用广泛的导航条制作实例详解

    导航条的使用很广,每个网站都会做出具有自己特色的导航条.最近特地去了解了各种类型的导航条,比如具有高亮显示的导航条,中英文互相切换的导航条,具有弹性动画的导航条,甚至是具有摩擦运动动画的导航条(文字下面有横线)等.每种导航条都有自己的特色,比如高亮显示的导航条看起来比较简单,但是视觉效果还不错,具有动画效果的导航条在视觉上也是有很好的效果. 接下来将会一一介绍4种应用比较广的导航条,即:高亮显示的导航条,中英文互相切换的导航条,具有弹性动画的导航条,具有摩擦运动动画的导航条. 1.高亮显示的导航

  • Java Springboot websocket使用案例详解

    什么是WebSocket WebSocket是一种在单个TCP连接上进行全双工通信的协议 - 为什么要实现握手监控管理 如果说,连接随意创建,不管的话,会存在错误,broken pipe 表面看单纯报错,并没什么功能缺陷等,但实际,请求数增加,容易导致系统奔溃.这边画重点. 出现原因有很多种,目前我这边出现的原因,是因为客户端已关闭连接,服务端还持续推送导致. 如何使用 下面将使用springboot集成的webSocket 导入Maven 首先SpringBoot版本 <parent> &l

  • java 虚拟机中对象访问详解

    java 虚拟机中对象访问详解 对象访问会涉及到Java栈.Java堆.方法区这三个内存区域. 如下面这句代码: Object objectRef = new Object(); 假设这句代码出现在方法体中,"Object objectRef" 这部分将会反映到Java栈的本地变量中,作为一个reference类型数据出现.而"new Object()"这部分将会反映到Java堆中,形成一块存储Object类型所有实例数据值的结构化内存,根据具体类型以及虚拟机实现的

  • java集合中的list详解

    1.List接口 该接口定义的元素是有序的且可重复的.相当于数学里面的数列,有序可重复 booleanaddAll(intindex,Collection<?extendsE>c);将指定集合中所有元素,插入至本集合第index个元素之后defaultvoidreplaceAll(UnaryOperatoroperator);替换集合中每一个元素值defaultvoidsort(Comparator<?superE>c);给集合中的元素进行排序Eget(intindex);获取集合

  • Java SpringBoot Validation用法案例详解

    目录 constraints分类 对象集成constraints示例 SpringBoot集成自动验证 集成maven依赖 验证RequestBody.Form对象参数 验证简单参数 验证指定分组 全局controller验证异常处理 自定义constraints @DateFormat @PhoneNo 使用自定义constraint注解 问题 提到输入参数的基本验证(非空.长度.大小.格式-),在以前我们还是通过手写代码,各种if.else.StringUtils.isEmpty.Colle

  • Java SpringBoot自动装配原理详解及源码注释

    目录 一.pom.xml文件 1.父依赖 2.启动器: 二.主程序: 剖析源码注解: 三.结论: 一.pom.xml文件 1.父依赖 主要是依赖一个父项目,管理项目的资源过滤以及插件! 资源过滤已经配置好了,无需再自己配置 在pom.xml中有个父依赖:spring-boot-dependencies是SpringBoot的版本控制中心! 因为有这些版本仓库,我们在写或者引入一些springboot依赖的时候,不需要指定版本! 2.启动器: 启动器也就是Springboot的启动场景; 比如sp

  • Java JVM中线程状态详解

    目录 线程在JVM中的状态 线程在JVM中的状态转换 前言: 在Java面试中,线程的状态也是被经常考察的知识点,今天我们就来聊一聊线程状态的那些事! 线程在JVM中的状态 查看线程在JVM中有哪些不同的状态,最简单的方式是查看Jdk源码的Thread.State类.以下内容来自JDK文档.在JVM中,一个线程可能处于下面的六种状态中的一种: NEW A thread that has not yet started is in this state. 没有开始执行的线程处于这种状态 RUNNA

  • SpringBoot 中使用RabbtiMq 详解

    目录 前言 pom.xml application.properties MailConstants (常量) RabbitConfig (rabbitMq的配置类) MailSendTask(定时任务,发送) MailReceiver(接收端) 使用总结 前言 如图使用redisTemplate 一样的简单方便 模拟发送邮件的情况 pom.xml <dependency> <groupId>org.springframework.boot</groupId> <

随机推荐