java中强引用、软引用、弱应用、虚引用

本文介绍了Java中四种引用类型的特性及应用场景:强引用、软引用、弱引用和虚引用。强引用是最常用的引用类型,软引用适用于创建内存敏感的高速缓存,弱引用则用于对象几乎不可达的情况,而虚引用主要用于跟踪对象的垃圾回收状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        在一次面试经历中,被问到java中的四种引用类型,平时工作中没有去深入的学习,只是在一次安卓开发过程中为了解决内存泄漏问题,使用到了弱引用。现在对java中的四种引用类型做一下简单的介绍。从JDK1.2开始,对象的引用被分为了四个级别:强引用、软引用、弱引用、虚引用,从而使程序更加灵活的控制对象的生命周期。

强引用:在我们平时编程中,用的最多的其实就是强引用,比如

User user = new User()


,则这个user就是一个强引用,如果一个对象具有强引用,那Java虚拟机宁愿抛出out of memory也不会对这个对象进行回收。


软引用:如果一个对象只具有软引用,如果java虚拟机内存空间足够,垃圾回收器就不会回收它,但当内存空间不足时,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。sr就是一个软引用。

SoftReference<User> sr = new SoftReference<User>(new User());




弱引用:如果一个对象只具有弱引用,则不管java虚拟机内存是否足够,在垃圾回收器扫描它所管辖的范围的过程,一旦gc发现对象为weakReference可达,就会把它放到ReferenceQueue,等待下次gc回收它所以在使用弱引用的时候,注意通过wr.get()判断对象是否已为null。

WeakReference<User> wr = new WeakReference<User>(new User());




虚引用:“虚引用”顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象 仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。 虚引用主要用来跟踪对象被垃圾回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列 (ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之 关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。程序如果发现某个虚引用已经被加入到引用队 列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。




### Java强引用引用的区别 #### 强引用 (Strong Reference) 强引用是最常见的引用类型,在Java中,通过简单的赋值操作即可创建强引用。只要存在强引用指向某个对象,则该对象就不会被垃圾回收机制所回收。 ```java Object obj = new Object(); ``` 上述代码片段展示了如何创建一个强引用实例[^1]。当程序不再需要此对象时,应显式解除引用或将变量设置为`null`以便让垃圾收集器能够回收资源。 #### 引用 (Weak Reference) 相比之下,引用是一种较形式的引用关系,它不会阻止目标对象成为垃圾回收的目标。即使当前内存空间充足,一旦触发GC周期,持有引用的对象也会被清理掉。为了实现这一点,可以利用`java.lang.ref.WeakReference<T>`类来构建引用: ```java import java.lang.ref.WeakReference; String str1 = new String("abc"); WeakReference<String> weakRefStr = new WeakReference<>(str1); ``` 这段代码说明了怎样定义并初始化一个字符串类型的引用实例[^2]。值得注意的是,由于引用不具备保持对象存活的能力,因此通常会配合`ReferenceQueue`一起使用,从而更好地管理这些即将消失的对象状态变化事件。 #### 主要差异对比 | 特征/属性 | 强引用 | 引用 | | --- | --- | --- | | 对象生命周期影响 | 阻碍垃圾回收;只有当所有强引用都被移除后才会考虑回收 | 不阻碍垃圾回收;每次GC都可能被清除 | | 创建方式 | `T t = new T();` 或者其他常规赋值表达式 | 使用`new WeakReference<>(referent)`构造函数 | | 应用场景 | 大多数情况下默认使用引用模式 | 缓存数据结构、监听器列表等不需要长期存在的场合 | #### 实际应用案例分析 对于缓存设计而言,如果希望某些条目能够在必要时刻自动释放其所占用的空间而不必手动干预的话,那么采用引用来保存键值对就是一种合理的选择。因为每当发生GC动作的时候,那些仅由引用维持着联系的数据项将会自然地被淘汰出局,进而达到节省内存的目的[^3]。 另一方面,考虑到性能因素以及潜在的风险——即频繁发生的GC可能导致大量不必要的对象销毁活动——开发者应当谨慎评估具体需求后再决定是否引入此类特性到项目当中去[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值