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

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

前言

我们知道 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断绝关系时才会被回收。它是日常编码中的默认引用方式,但如果管理不当,可能导致内存泄漏

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值