Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >强引用,软引用,弱引用,幻象引用有什么区别?

强引用,软引用,弱引用,幻象引用有什么区别?

作者头像
王小明_HIT
发布于 2020-05-25 15:37:21
发布于 2020-05-25 15:37:21
4.4K00
代码可运行
举报
文章被收录于专栏:程序员奇点程序员奇点
运行总次数:0
代码可运行

强引用,软引用,弱引用,幻象引用有什么区别?

不同的引用类型,主要体现的是对象的不同的可达性(reachable)状态和对垃圾收集的影响。

  • 所谓强引用 (Strong Reference) 就是我们常见的普通对象引用,只要还有强引用指向一个对象,就能表明对象还活着,垃圾回收不回收这种对象
  • 软引用,是一种相对强引用弱化一些的引用,只有当 JVM 认为内存不足时,才会试图回收软引用指向的对象。JVM 会确保在排除 OutOfMemoryError 之前,清理软引用指向的对象,软引用通常用来实现内存敏感的缓存,如果还有空闲内存,就可以暂时保留缓存,当内存不足时,清理掉,这样就保证了使用缓存的同时,不会耗尽内存。
  • 弱引用,比软引用拥有更短的生命周期,在垃圾回收线程扫码所管辖的内存区域的过程中,一大发现了只具有弱引用的对象,不管当前内存空间是否足够,都会回收它的内存,由于垃圾回收器是一个优先级,因此不一定很快发现那些只有弱引用的对象。
  • 虚引用,形同虚设 ,虚引用不会决定对象的生命周期,如果一个对象仅持有虚引用,其实就和没有任何引用一样。在任何时候都可能被垃圾回收器回收。虚引用和软引用的一个区别是,虚引用必须和引用队列(ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。

image

四种引用类型对比

引用类型

被垃圾回收时间

用途

生存时间

强引用

从来不会

对象的一般状态

JVM 停止运行时终止

软引用

当内存不足时

对象缓存

内存不足时终止

弱引用

正常垃圾回收时

对象缓存

垃圾回收后终止

虚引用

正常垃圾回收时

跟踪对象的垃圾回收

垃圾回收后终止

四种引用的应用场景

强引用

强引用是使用最普遍的引用,一般声明如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Object strongReference = new Object();

如果要对强引用进行垃圾回收,需要设置强引用对象为 null ,或者让其超出对象的生命周期范围,则认为改对象不存在引用。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
strongReference = null;

可以看下 ArrayList 是如何进行内存释放的

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
   public void clear() {
        modCount++;
        // clear to let GC do its work
        for (int i = 0; i < size; i++)
            elementData[i] = null;
        size = 0;
    }

软引用

软引用可用来实现内存敏感的高速缓存。

使用如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 强引用
String strongReference = new String("abc");
// 软引用
String str = new String("abc");
SoftReference<String> softReference = new SoftReference<String>(str);

软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ReferenceQueue refQueue = new ReferenceQueue();
SoftReference softRef = new SoftReference(obj, refQueue);

软引用垃圾回收

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if(JVM内存不足) {
      // 将软引用中的对象引用置为null
      str = null;
      // 通知垃圾回收器进行回收
      System.gc();
  }

代表软引用的类:java.lang.ref.SoftReference 代表弱引用的类:java.lang.ref.WeakReference 代表虚引用的类:java.lang.ref.PhantomReference 他们同时继承了:java.lang.ref.Reference

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 public static void soft() throws Exception {
        Object obj = new Object();
        SoftReference<Object> softRef = new SoftReference<Object>(obj);
        System.out.println(softRef.get()); //有时候会返回Null
        // java.lang.Object@f9f9d8 System.out.println(refQueue.poll());
        // null
        // 清除强引用,触发GC
        obj = null;
        //System.gc();
        System.out.println(softRef.get());
        //Thread.sleep(200);
        //System.out.println(refQueue.poll());
    }

弱引用

弱引用和软引用的区别在于:弱引用拥有更短暂的生命周期,不管内存够不够,都会回收,都会回收它的内存。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Object obj = new Object();
WeakReference<Object> weakReference = new WeakReference<Object>(obj);
obj = null;
System.gc();
System.out.println(weakReference.get());// 有时候会返回Null
System.out.println(weakReference.isEnqueued());//判断是否有垃圾回收标记,表示即将回收的垃圾

虚引用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 // 虚引用
Object obj = new Object();
ReferenceQueue refQueue = new ReferenceQueue();
PhantomReference<Object> phantomReference = new PhantomReference<Object>(obj, refQueue);
System.out.println(phantomReference.get());  // 永远返回Null
System.out.println(phantomReference.isEnqueued()); //返回时否从队列中删除

对象可达性分析

  • 强可达(Strongly Reachable),就是当一个对象可以有一个或多个线程可以不通过各种引用访问到的情况。比如,我们新创建一个对象,那么创建它的线程对它就是强可达。
  • 软可达(Softly Reachable),就是当我们只能通过软引用才能访问到对象的状态。
  • 弱可达(Weakly Reachable),类似前面提到的,就是无法通过强引用或者软引用访问,只能通过弱引用访问时的状态。这是十分临近fnalize状态的时机,当弱引用被清除的时候,就符合finalize的条件了。
  • 幻象可达(Phantom Reachable),上面流程图已经很直观了,就是没有强、软、弱引用关联,并且finalize过了,只有幻象引用指向这个对象的时候。当然,还有一个最后的状态,就是不可达(unreachable),意味着对象可以被清除了。

Java中4种引用的级别和强度由高到低依次为:强引用 -> 软引用 -> 弱引用 -> 虚引用

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-05-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员奇点 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Java后端面试,强、软、弱、幻象引用的概念以及使用场景
在 Java 中,理解和正确使用各种引用类型(强引用、软引用、弱引用、幻象引用)对有效的内存管理和垃圾回收至关重要。下面我们详细解读这些引用类型的区别及其具体使用场景。
小马哥学JAVA
2024/06/29
1620
简单直白教你理解Java中四大引用强引用,软引用,弱引用,虚引用
我属于自学型的,所以知识不够系统,只能是一边儿工作一边查漏补缺,在此要对那些写技术文章的人由衷的说句谢谢,谢谢各位大神们的分享 ONE,强引用(StrongReference) 概念介绍: 在此说明一
fanfan
2018/01/24
7390
每天一个Java面试题——Java的四大引用是?
在Java中,引用类型主要有四种:强引用、软引用、弱引用和虚引用。它们之间的区别主要体现在垃圾回收器对它们的处理方式上。本文分别介绍这四种引用类型,并给出相应的代码示例。
灬沙师弟
2024/08/06
3220
每天一个Java面试题——Java的四大引用是?
老徐和阿珍的故事:强引用、软引用、弱引用、虚引用,傻傻分不清楚
看着老徐的窘态,阿珍笑出来了声。老徐起身刚要走,阿珍一把拽住老徐,说:“跟你开玩笑呢,问你个正事,我一直分不清Java的强引用、软引用、弱引用、虚引用,给我讲讲呗。” 老徐立刻自信满满地坐下,说:“那你可问对人了,我对这方面颇有研究。这四种引用级别由高到低依次是:强引用、软引用、弱引用、虚引用。”
万猫学社
2022/06/14
4180
基础篇:JAVA引用类型和ThreadLocal
平时并发编程,除了维护修改共享变量的场景,有时我们也需要为每一个线程设置一个私有的变量,进行线程隔离,java提供的ThreadLocal可以帮助我们实现,而讲到ThreadLocal则不得不讲讲java的四种引用,不同的引用类型在GC时表现是不一样的,引用类型Reference有助于我们了解如何快速回收某些对象的内存或对实例的GC控制
潜行前行
2021/06/25
4130
Java 的强引用、弱引用、软引用、虚引用
        强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它。如下:
爱撸猫的杰
2019/03/28
3.7K0
Java 的强引用、弱引用、软引用、虚引用
强引用、软引用、弱引用、幻象引用有什么区别?
特点:我们平常典型编码Object obj = new Object()中的obj就是强引用。通过关键字new创建的对象所关联的引用就是强引用。 当JVM内存空间不足,JVM宁愿抛出OutOfMemoryError运行时错误(OOM),使程序异常终止,也不会靠随意回收具有强引用的“存活”对象来解决内存不足的问题。对于一个普通的对象,如果没有其他的引用关系,只要超过了引用的作用域或者显式地将相应(强)引用赋值为 null,就是可以被垃圾收集的了,具体回收时机还是要看垃圾收集策略。
葆宁
2019/04/18
5780
好未来面试官:说说强引用、软引用、弱引用、幻象引用有什么区别?
在Java语言中,除了原始数据类型的变量,其他所有都是所谓的引用类型,指向各种不同的对象,理解引用对于掌握Java对象生命周期和JVM内部相关机制非常有帮助。
Java程序猿
2021/07/22
4070
阿里面试: 说说强引用、软引用、弱引用、虚引用吧
我们都知道 JVM 垃圾回收中,GC判断堆中的对象实例或数据是不是垃圾的方法有引用计数法和可达性算法两种。
乔戈里
2020/05/25
3.7K0
阿里面试: 说说强引用、软引用、弱引用、虚引用吧
JAVA面试50讲之3:强引用、软引用、弱引用、虚引用的区别?
  在Java中,虽然不需要程序员手动去管理对象的生命周期,但是如果希望某些对象具备一定的生命周期的话(比如内存不足时JVM就会自动回收某些对象从而避免OutOfMemory的错误)就需要用到软引用和弱引用了。
用户1205080
2019/01/02
2K0
一文带你读懂Java的强引用、软引用、弱引用、虚引用
开讲前,我们先回顾下JVM的基本结构。根据《Java虚拟机规范(Java SE 7版)》。Java虚拟机所管理的内存将会包括以下几个运行时数据区域:
后台技术汇
2022/05/28
4860
一文带你读懂Java的强引用、软引用、弱引用、虚引用
java强引用、软引用、弱引用、虚引用以及FinalReference
基于JDK1.8 rt.jar是java中的基础类库,在它的 java.lang.ref包下,有着一堆关于引用的类。软引用、弱引用以及虚引用的定义就在其中。另外还有一个FinalReference。
早安嵩骏
2020/08/11
1.3K0
Java 引用类型简述
强引用 ( Strong Reference ) 强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。 ps:强引用其实也就是我们平时A a = new A()这个意思。 强引用特性 强引用可以直接访问目标对象。 强引用所指向的对象在任何时候都不会被系统回收。 强引用可能导致内存泄漏。 Final Reference 当前类是否是
tomas家的小拨浪鼓
2018/06/27
7480
Android中的引用类型:Weak Reference, Soft Reference, Phantom Reference 和 WeakHashMap
在Android开发中,内存管理是一个非常重要的话题。为了更好地管理内存,Java和Android提供了多种引用类型,包括Weak Reference、Soft Reference、Phantom Reference以及WeakHashMap。这些引用类型在不同的场景下可以帮助我们更有效地管理内存,避免内存泄漏。
井九
2024/10/12
1440
Java中的强引用、软引用、弱引用与虚引用
Java语言提供了一种强大的垃圾回收机制,通过不同类型的引用来管理内存中的对象。引用类型包括强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)和虚引用(Phantom Reference)。这些引用类型允许开发者在不同的内存压力条件下对对象进行不同程度的管理,优化内存使用和性能。本文将深入探讨Java中的这四种引用类型,涵盖它们的定义、使用场景、实现原理以及在实际应用中的最佳实践。
九转成圣
2024/08/05
2660
Java的强引用,软引用,弱引用,虚引用及其使用场景
从 JDK1.2 版本开始,Java 把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期。这四种级别由高到低依次为:强引用、软引用、弱引用和虚引用。
用户3596197
2018/10/15
5K0
Java 的四种引用:强引用、弱引用、软引用和虚引用
在 Java 中,引用是一种指向对象的引用类型。不同类型的引用在垃圾回收机制中的行为各不相同,影响对象的生命周期和内存管理。以下是 Java 中的四种引用类型:强引用、弱引用、软引用和虚引用。
繁依Fanyi
2024/10/25
3460
【JVM】深入理解Java引用类型:强引用、软引用、弱引用和虚引用
导言: 在Java中,引用类型是内存管理的重要组成部分。本文将深入介绍强引用、软引用、弱引用和虚引用,为您解析它们的特性以及如何在实际应用中巧妙利用。
人不走空
2024/02/21
7070
【JVM】深入理解Java引用类型:强引用、软引用、弱引用和虚引用
什么是强引用、软引用、弱引用、虚引用?
强引用(StrongReference):一般指的是对像被new出来,强引用一般不会被jvm收回,但会报OutOfMemory(内存不足)。
逍遥壮士
2020/11/24
1.8K0
什么是强引用、软引用、弱引用、虚引用?
Java中四种引用类型:强引用,软引用,弱引用,虚引用
类似Object obj = new Object()这类似的引用,强引用在程序代码中普遍存在,只要强引用在,垃圾搜集器永远不会搜集被引用的对象。也就是说,宁愿出现内存溢出(OutOfMemoryError),也不会回收这些对象
gang_luo
2020/08/13
9250
Java中四种引用类型:强引用,软引用,弱引用,虚引用
推荐阅读
相关推荐
Java后端面试,强、软、弱、幻象引用的概念以及使用场景
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验