当前位置: 首页 > news >正文

强引用?软引用?弱引用?虚引用?一文带你彻底搞懂!!

强引用?软引用?弱引用?虚引用?一文带你彻底搞懂!!

    • 前言
    • 引用级别
      • 强引用
      • 软引用
      • 弱引用
      • 虚引用
    • 总结

前言

我们知道 JVM 的 GC 是不受程序控制的,只要满足条件就会自动触发

那他是根据什么触发的呢?

在 什么是 GC Roots??一文带你看懂!! 这篇文章中,我们了解到是 GC Roots

GC Roots 向下追溯,搜索,会产生一个叫做 Reference Chain 的链条,当一个对象不能和任何一个 GC Roots 产生关系时,就会被无情诛杀

那么,反过来讲:能够找到 Reference Chain 的对象,就一定会存活吗?

带着这个问题,我们引申出今天的话题——引用级别

引用级别

对象对于另一个对象的引用,要看关系牢不牢靠,可能在链表的其中一环,就断掉了。

在这里插入图片描述

根据发生 GC 时,这条链条的表现,可以对这个引用关系进行更加细致的划分。

它们的关系,可以分为强引用、软引用、弱引用、虚引用等。

强引用

当内存空间不足,系统撑不住了的时候, JVM 就会抛出 OutOfMemoryError ,即 OOM 异常,即使程序异常终止了,这种对象也不会被回收。

这种引用属于我们最常见的普通对象引用,也是最强硬的存在,只有在和 GC Roots 断绝关系时,才会被消灭掉,比如超过了引用的作用域或者显式地将相应强引用赋值为 null

这种引用,我们每天都在编码,例如 new 一个普通的对象

Object obj = new Object();

这种方式可能是有问题的。假如你的系统被大量用户(User)访问,你需要记录这个 User 访问的时间。可惜的是,User 对象里并没有这个字段,所以我们决定将这些信息额外开辟一个空间进行存放。

static Map<User,Long> userVisitMap = new HashMap<>();...userVisitMap.put(user, time);

当你用完了 User 对象,其实你是期望它被回收掉的。但是,由于它被 userVisitMap 引用,我们没有其他手段 remove 掉它。这个时候,就发生了内存泄漏(memory leak)。

这种情况还通常发生在一个没有设定上限的 Cache 系统,由于设置了不正确的引用方式,加上不正确的容量,很容易造成 OOM。

软引用

软引用用于维护一些可有可无的对象。在内存足够的时候,软引用对象不会被回收,只有在内存不足时,系统则会回收软引用对象,如果回收了软引用对象之后仍然没有足够的内存,才会抛出内存溢出异常。

可以看到,这种特性非常适合用在缓存技术上,比如网页缓存、图片缓存等

Object object = new Object();SoftReference<Object> softRef = new SoftReference(object);

弱引用

弱引用对象相比较软引用,要更加无用一些,它拥有更短的生命周期。

当 JVM 进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。弱引用拥有更短的生命周期

它的应用场景和软引用类似,可以在一些对内存更加敏感的系统里采用。它的使用方式类似于这段的代码:

Object object = new Object();WeakReference<Object> softRef = new WeakReference(object);

虚引用

这是一种形同虚设的引用,在现实场景中用的不是很多。虚引用必须和引用队列(ReferenceQueue)联合使用。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。虚引用主要用来跟踪对象被垃圾回收的活动。

实际上,虚引用的 get,总是返回 null。

Object object = new Object();ReferenceQueue queue = new ReferenceQueue();// 虚引用,必须与一个引用队列关联PhantomReference pr = new PhantomReference(object, queue);

基于虚引用,有一个更加优雅的实现方式,那就是 Java 9 以后新加入的 Cleaner,用来替代 Object 类的 finalizer 方法。

总结

  • 强引用 是最常见和最强的引用类型,只有当对象与GC Roots断绝关系时才会被回收。它是日常编码中的默认引用方式,但如果管理不当,可能导致内存泄漏

  • 软引用 适合用于那些内存充足时不需要回收,但在内存不足时可以被回收的对象。软引用常见于缓存实现,如网页缓存和图片缓存加粗样式

  • 弱引用 相比软引用更弱,即使内存充足,垃圾回收时也会被回收。它适用于对内存使用更加敏感的应用场景。

  • 虚引用 是最弱的引用类型,几乎不能防止对象被回收。它通常与引用队列一起使用,用于跟踪对象的垃圾回收活动。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 演唱会售票系统(Springboot+MySQL+Mybatis+BootStrap)
  • flask使用定时任务flask_apscheduler(APScheduler)
  • vue3解决报错:ResizeObserver loop completed with undelivered notifications
  • MinIO - 服务端签名直传(前端 + 后端 + 效果演示)
  • git查看版本,查看安装路径、更新版本
  • 图解 RocketMQ 架构
  • 三星首款智能戒指 Galaxy Ring 将于7月24日上市,售价399美元
  • 深入理解 KVO
  • 【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 找单词(200分) - 三语言AC题解(Python/Java/Cpp)
  • 真实测评网上较火的两款智能生成PPT产品:秒出PPTAI PPT
  • uni-app/vue项目如何封装全局消息提示组件
  • Java接口案例
  • HTML 标签简写和全称及其对应的中文说明和实例
  • SQL MySQL定时器/事件调度器(Event Scheduler)
  • Deepspeed : AttributeError: ‘DummyOptim‘ object has no attribute ‘step‘
  • JavaScript-如何实现克隆(clone)函数
  • SegmentFault for Android 3.0 发布
  • Android 控件背景颜色处理
  • ECMAScript6(0):ES6简明参考手册
  • ERLANG 网工修炼笔记 ---- UDP
  • Github访问慢解决办法
  • github指令
  • JS实现简单的MVC模式开发小游戏
  • miaov-React 最佳入门
  • Netty 框架总结「ChannelHandler 及 EventLoop」
  • PHP 使用 Swoole - TaskWorker 实现异步操作 Mysql
  • Quartz实现数据同步 | 从0开始构建SpringCloud微服务(3)
  • react 代码优化(一) ——事件处理
  • react-native 安卓真机环境搭建
  • Spark学习笔记之相关记录
  • Swift 中的尾递归和蹦床
  • 编写高质量JavaScript代码之并发
  • 大型网站性能监测、分析与优化常见问题QA
  • 基于webpack 的 vue 多页架构
  • 计算机在识别图像时“看到”了什么?
  • 简单数学运算程序(不定期更新)
  • 来,膜拜下android roadmap,强大的执行力
  • 聊聊springcloud的EurekaClientAutoConfiguration
  • 如何胜任知名企业的商业数据分析师?
  • 学习笔记DL002:AI、机器学习、表示学习、深度学习,第一次大衰退
  • 一个6年java程序员的工作感悟,写给还在迷茫的你
  • LevelDB 入门 —— 全面了解 LevelDB 的功能特性
  • Nginx实现动静分离
  • Semaphore
  • 浅谈sql中的in与not in,exists与not exists的区别
  • ​​​【收录 Hello 算法】9.4 小结
  • ​用户画像从0到100的构建思路
  • ‌移动管家手机智能控制汽车系统
  • #考研#计算机文化知识1(局域网及网络互联)
  • #在线报价接单​再坚持一下 明天是真的周六.出现货 实单来谈
  • (C语言)fgets与fputs函数详解
  • (floyd+补集) poj 3275
  • (Git) gitignore基础使用
  • (k8s)Kubernetes 从0到1容器编排之旅
  • (Matlab)使用竞争神经网络实现数据聚类