JVM虚拟机(五)强引用、软引用、弱引用、虚引用

这篇具有很好参考价值的文章主要介绍了JVM虚拟机(五)强引用、软引用、弱引用、虚引用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

引文:

在 Java 中一共存在 4 种引用:强、软、弱、虚。它们主要指的是,在进行垃圾回收的时候,对于不同的引用垃圾回收的情况是不一样的。下面我们就一起来看一下这 4 种引用。

一、强引用

强引用:只有所有 GC Root 对象都不通过【强引用】引用该对象,该对象才能被垃圾回收。

强引用是比较常见的,比如说下面这段代码种,这个 user 就是强引用:

User user = new User();

强引用的特点有哪些呢?如下图所示:

JVM虚拟机(五)强引用、软引用、弱引用、虚引用,# JVM,jvm,java,算法

现在有一个 GC Root,我们之前讲过 GC Root 是用来定位哪些对象是存活的。

  • 假如说 GC Root 关联到了 User 对象,那就证明这个 User 对象是存活的,则这个 User 对象一直都不会被垃圾回收,即使出现了内存不足,抛出 OOM 异常,也不会回收强引用的对象。
  • 只有当 GC Root 不再关联 User 对象,那这个对象才有可能会被垃圾回收器进行回收。

以上就是强引用的特点。


二、软引用

软引用:仅有软引用引用该对象时,在垃圾回收后,内存仍不足时会再次触发垃圾回收。

我们先来看一段代码:

User user = new User();
SoftReference softReference = new SoftReference(user);

在这段代码中,我们先创建了一个 User 对象,然后又创建了一个 SoftReference 对象并且包装了 User 对象。它们的关系如下图所示:

JVM虚拟机(五)强引用、软引用、弱引用、虚引用,# JVM,jvm,java,算法

首先 GC Root 能够关联到 SoftReference 对象,然后当前的 SoftReference 又会关联 User 对象。大家注意,SoftReference 对象和 User 对象之间的关联是使用的虚线,因为这种关联属于软引用。

在进行垃圾回收的时候,一开始并不会对 user 对象进行垃圾回收。由于 user 对象是一个软引用,如果在第一次垃圾回收之后内存还是不够,马上又进行了一次垃圾回收,这个时候软引用 User 对象就会被垃圾回收器回收了。

以上就是软引用的介绍,它必须配合 SoftReference 进行使用。


三、弱引用

弱引用:仅有弱引用引用该对象时,在垃圾回收的时候,无论内存是否充足,都会回收弱引用对象。

弱引用和软引用的使用有些类似,我们来看这样一段代码:

User user = new User();
WeakReference weakReference = new WeakReference(user);

在这段代码中,先创建了一个 User 对象,然后创建了一个 WeakReference 对象并且包装了 User 对象,他们的关系如下图所示:

JVM虚拟机(五)强引用、软引用、弱引用、虚引用,# JVM,jvm,java,算法

首先,GC Root 关联到的是 WeakReference 对象,然后由 WeakReference 对象去关联了 User 对象,这里也是用虚线表示的。目前这个 User 对象就是一个弱引用。

在进行垃圾回收的时候。一旦内存不够用了,User 对象作为一个弱引用对象,就会被垃圾回收器回收掉。

关于弱引用有一个经典的例子,就是 ThreaLocal 内存泄露的问题

JVM虚拟机(五)强引用、软引用、弱引用、虚引用,# JVM,jvm,java,算法

在 ThreadLocal 中有一个 Entry 对象,它继承了 WeakReference,然后在构造函数里面调用了 super(k) 方法,也就表示了当前构造函数中的 ThreadLocal<?> 是一个弱引用,一旦内存不够的时候进行了垃圾回收,就会把 k 对象回收掉。但是 value 使用的是 = 进行赋值,就是一个强引用,并不会被垃圾回收器进行回收。所以说这块儿就可能产生内存泄漏。

以上就是弱引用的说明。


四、虚引用

虚引用:必须配合引用队列使用,被引用对象回收时,会将虚引用入队,由 Reference Handler 线程调用虚引用相关方法释放直接内存。

为了方便理解,我们来看这样一段代码:

User user = new User();
ReferenceQueue referenceQueue = new ReferenceQueue();
PhantomReference phantomReference = new PhantomReference(user, referenceQueue);

在这段代码中,先创建了一个 User 对象,然后创建了一个 ReferenceQueue 对象(就是一个引用队列),最后创建了一个 PhantomReference 对象并且包装了 User 对象和 ReferenceQueue 对象。它们之间的关系如下图所示:

JVM虚拟机(五)强引用、软引用、弱引用、虚引用,# JVM,jvm,java,算法

首先,GC Root 直接关联的是 PhantomReference 虚引用对象,一个是 X,另一个是 Y。这两个 PhantomReference 对象分别去引用了 User1 对象和 User2 对象。

大家可能会想,这里面哪里能体现 ReferenceQueue 队列呢?是这样的,将来如果发生了垃圾回收,把 User1 和 User2 这两个对象回收掉了,那么 PhantomReference 虚引用对象本身在进行垃圾回收发生的时候,会把虚引用对象 X 和 Y 加入到 ReferenceQueue 引用队列中,如下图所示:

JVM虚拟机(五)强引用、软引用、弱引用、虚引用,# JVM,jvm,java,算法

把 X 和 Y 虚引用对象加入到 ReferenceQueue 引用队列中之后,引用队列就会配合 Reference Handler 这个线程来去释放虚引用对象所关联的一些外部资源。

比如说 User1 和 User2 已经被垃圾回收掉了,但是回收这两个对象只是释放了 Java 的堆内存资源,它们在使用的过程中有可能会使用一些外部的资源,这些外部资源有可能不是 Java 的内存,有可能使用的是系统的直接内存,那这些内存什么时候释放呢?这些内存必须要等 Java 对象回收掉之后,才能去释放这些外部的资源内存。所以说就需要把这些虚引用对象放入到引用队列中,先记录哪些对象被回收了,然后由 Reference Handler 根据队列的内容去回收资源就可以了。比如我们示例中的 X 和 Y 两个虚引用对象,它们关联的 User 对象已经被回收掉了,这个时候我们也应该把 X 和 Y 对应的外部资源进行释放,有一个专门的线程来进行释放,就叫 Reference Handler。它就会去从引用队列中不断地把这些虚引用对象 X 和 Y 取出来,然后把它们占用的外部资源进行释放。

以上就是虚引用对象的说明了,它需要配合 ReferenceQueue 引用队列才能使用。

补充: 软引用和弱引用也可以通过引用队列去释放自身的资源。

下面我们总结一下这四种引用类型。


五、总结

强引用、软引用、弱引用、虚引用的区别?

  • 强引用:比较常见,只要 GC Root 能关联到,就不会被回收。
  • 软引用:需要配合 SoftReference 使用,当垃圾被多次回收,内存依然不够的时候会回收软引用对象。
  • 弱引用:需要配合 WeakReference 使用,只要进行了垃圾回收,就会把弱引用对象回收。
  • 虚引用:必须配合引用队列使用,被引用对象回收时,会将虚引用入队,由 Reference Handler 线程调用虚引用相关方法释放直接内存等外部资源。

整理完毕,完结撒花~🌻文章来源地址https://www.toymoban.com/news/detail-852116.html

到了这里,关于JVM虚拟机(五)强引用、软引用、弱引用、虚引用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Java虚拟机】JVM垃圾回收机制和常见回收算法原理

    1.垃圾回收机制 (1)什么是垃圾回收机制(Garbage Collection, 简称GC) 指自动管理动态分配的内存空间的机制,自动回收不再使用的内存,以避免内存泄漏和内存溢出的问题 最早是在1960年代提出的,程序员需要手动管理内存的分配和释放 这往往会导致内存泄漏和内存溢出等问

    2024年02月02日
    浏览(50)
  • 49天精通Java,第34天,finalize、引用计数、JVM停止复制、JVM即时编译器

    在Java中,finalize()是一个Object类的方法,用于在对象被垃圾收集器回收之前执行一些清理操作。当一个对象成为垃圾时,它的finalize()方法会被自动调用。 finalize()方法的语法格式如下:

    2024年02月07日
    浏览(46)
  • JVM零基础到高级实战之对象存活算法引用计数法存在的特点分析

    JVM零基础到高级实战之对象存活算法引用计数法存在的特点分析 JVM零基础到高级实战之对象存活算法引用计数法存在的特点分析 优点 引用计数收集器可以很快的执行,交织在程序运行中。对程序需要不被长时间打断的实时环境比较有利。 缺点 无法检测出循环引用。如父对

    2024年02月15日
    浏览(94)
  • JVM(Java虚拟机)-史上最全、最详细JVM笔记

    一、JVM概述 1、1为什么要学习JVM 1、2虚拟机 1、3JVM作用 1、4JVM整体组成部分  二、JVM结构--类加载器 2、1类加载子系统 2、2类加载过程 2、2、1加载 2、2、2链接 2、2、3初始化 2、3类加载器分类 2.3.1 引导类加载器(启动类加载器 BootStrap ClassLoader) 2.3.2 扩展类加载器(Extension ClassL

    2024年02月03日
    浏览(64)
  • JVM(Java虚拟机)

    目录 1.JVM 简介 2. JVM 运行时数据区 2.1程序计数器 2.栈 3.堆 4.方法区 3.类加载 1.loading 2.linking 1.验证 2.准备 3.解析 3.Initializing 4.双亲委派模型 5.JVM垃圾回收机制 1.劣势 2.回收什么 3.垃圾回收具体怎么回收 1.找垃圾 方法: 问题: 2.释放垃圾 JVM 是 Java Virtual Machine 的简称,意为 Java虚

    2024年02月01日
    浏览(54)
  • Java虚拟机快速入门 | JVM引言、JVM内存结构、直接内存

    目录 一:JVM引言 1. 什么是 JVM ? 2. 常见的 JVM 3. 学习路线 二:JVM内存结构 1. 程 序 计 数 器(PC Register) 2. 虚 拟 机 栈(JVM Stacks) 3. 本 地 方 法 栈(Native Method Stacks) 4. 堆(Heap) 5. 方 法 区(Method Area) 三:直接内存 tips: 首先给大家推荐两款好用的免费软件:动图抓取软

    2024年02月05日
    浏览(64)
  • Java虚拟机(JVM)框架

    见:GitHub - eHackyd/Java_JVM: Java虚拟机(JVM)框架的学习笔记

    2024年02月10日
    浏览(51)
  • Jvm --java虚拟机(上)

    为什么学习jvm 如果你这辈子只甘心做一个平庸的Java码农,那么你可以利用阅读本文的时间去学习其他新的技术知识,但是如果你想成为一个更更更更优秀的中高级程序员!那么请继续阅读本文,希望这篇文章会对你有所帮助,那么学习jvm有啥好处嘞? 首先: 你能够明白为什

    2024年02月03日
    浏览(64)
  • JVM——Java虚拟机详解

    JVM——Java虚拟机,它是Java实现平台无关性的基石。 Java程序运行的时候,编译器将Java文件编译成平台无关的Java字节码文件(.class),接下来对应平台JVM对字节码文件进行解释,翻译成对应平台匹配的机器指令并运行。 同时JVM也是一个跨语言的平台,和语言无关,只和class的文

    2024年01月19日
    浏览(79)
  • JVM(Java虚拟机)详解

    目录 一、JVM内存区域划分   1. 什么是内存区域划分以及为啥要进行区域划分   2. JVM内存区域划分详解   3. 堆区详解:    4. 给一段代码,问某个变量是在那个区域上? 二、JVM类加载机制   1.类加载的过程   2. 类加载的时机   3. 双亲委派模型(经典面试) 三、JVM垃圾回收

    2024年02月15日
    浏览(66)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包