前言

判断对象是否要回收有引用计数法和可达性算法两种方式,无论哪种都离不开引用,本文将介绍Java的四种引用。


一、概述

二、详解

1. 强引用

概述

在Java程序中,强引用是最常见的也是默认的。new了一个对象,并将其指向一个变量,这个变量就成为指向该对象的一个强引用。

特点

  1. 强引用可以直接访问目标对象;
  2. 强引用所指向的对象在任何时候都不会被系统回收;
  3. 强引用可能导致内存泄漏。

实现方式

Object obj = new Object()	//这里的obj就是一个强引用
Object obj = new Object(); // 声明强引用
SoftReference<Object> sf = new SoftReference<>(obj);
obj = null; //销毁强引用
Object obj = new Object(); // 声明强引用
WeakReference<Object> wf = new WeakReference<>(obj);
obj = null; //销毁强引用
Object obj = new Object(); // 声明强引用
ReferenceQueue phantomQueue = new ReferenceQueue();
PhantomReference<Object> pf = new PhantomReference<>(obj, phantomQueue);
obj = null;

2. 软引用

概述

软引用是用来描述一些还有用,但非必需的对象。只被软引用关联着的对象,在系统将要发生内存溢出异常前,会把这些对象列进回收范围之中进行第二次回收,如果这次回收还没有足够的内存,才会抛出内存溢出异常。

特点

  1. 软引用所指向的对象,内存溢出前才被系统回收;
  2. 软引用被回收后还没有足够的内存,仍会抛出内存溢出异常;
  3. GC 决定收回软可达对象时,会清理软引用,并可选地把引用存放到一个引用队列(Reference Queue)。

场景

软引用通常用来实现内存敏感的缓存。比如:可以使用软引用来缓存最近使用的图片或文本,一旦内存不足,垃圾回收器就会回收这些对象,从而释放内存。

实现方式

Object obj = new Object(); // 声明强引用
SoftReference<Object> sf = new SoftReference<>(obj);
obj = null; //销毁强引用

3. 弱引用

概述

弱引用也是用来描述那些非必需对象,但是在系统GC时,只要发现弱引用,不管系统堆空间使用是否充足,都会回收掉只被弱引用关联的对象。 (但是,由于垃圾回收器的线程通常优先级很低,因此,并不一定能很快地发现持有弱引用的对象。在这种情况下,弱引用对象可以存在较长的时间。)

特点

弱引用所指向的对象,被发现就会被系统回收;

场景

  1. 缓存中存放的一些临时的数据。如,ThreadLocal;
  2. 多线程中经常被用来监控对象是否被垃圾回收器标记。

实现方式

Object obj = new Object(); // 声明强引用
WeakReference<Object> wf = new WeakReference<>(obj);
obj = null; //销毁强引用

4. 虚引用

概述

所有引用类型中最弱的一个。一个对象是否有虚引用的存在,完全不会决定对象的生命周期。

特点

  1. 不能单独使用,虚引用必须和引用队列一起使用;
  2. 一个对象只被虚引用变量引用时,垃圾回收器会将该对象加入引用队列中;
  3. 无法通过虚引用来获取被引用的对象(当试图通过虚引用的get()方法取得对象时,总是null)。

场景

在回收该对象之前,虚引用变量将被放入引用队列中,因此通常用于在对象被回收时执行必要的清理工作。例如:

  1. 关闭数据库连接或释放资源在并发编程中;
  2. 实现一些高级的对象生命周期管理,例如,对象池和线程池等。(追踪对象的生命周期,并在对象不再使用时及时清理它们,从而保证系统的可靠性和性能)

实现方式

Object obj = new Object(); // 声明强引用
ReferenceQueue phantomQueue = new ReferenceQueue(); //须和引用队列一起使用
PhantomReference<Object> pf = new PhantomReference<>(obj, phantomQueue);
obj = null;

你知道 Java 有哪些引用吗?的更多相关文章

  1. Java学习之强引用,弱引用,软引用 与 JVM

    1.java内存管理分为内存分配和内存回收,都不需要程序员负责. 2.垃圾回收的机制主要是看对象是否有引用指向该对象.  java对象的引用包括  强引用 软引用 弱引用 虚引用 3.强引用 是指创建 ...

  2. Java web项目引用java项目,类型找不到

    Java web项目引用java项目,类型找不到 错误信息: java.lang.ClassNotFoundException: org.codehaus.jackson.map.ObjectMapp ...

  3. Java四种引用包括强引用,软引用,弱引用,虚引用。

    Java四种引用包括强引用,软引用,弱引用,虚引用. 强引用: 只要引用存在,垃圾回收器永远不会回收Object obj = new Object();//可直接通过obj取得对应的对象 如obj.e ...

  4. 闲来无事,用Java的软引用写了一个山寨的缓存

    闲来无事,用Java的软引用写了一个山寨的缓存 博客分类: java基础 众所周知java中的引用分为 StrongReference.SoftReference.WeakReference.Phan ...

  5. Java 集合 持有引用 & WeakHashMap

    Java 集合 持有引用 & WeakHashMap @author ixenos 摘要:强引用.弱引用.WeakHashMap动态回收步骤 Reference引用对象 可获得的(reacha ...

  6. java到底是引用传递还是值传递?

    今天我们来讲讲一个在学习中容易误解的问题,面试中也偶尔问到,java方法调用时到底是值传递还是引用传递? 首先,请大家来做一个判断题,下面的3个问题是否描述正确 1. java基本数据类型传递是值传递 ...

  7. Java四种引用--《深入理解Java虚拟机》学习笔记及个人理解(四)

    Java四种引用--<深入理解Java虚拟机>学习笔记及个人理解(四) 书上P65. StrongReference(强引用) 类似Object obj = new Object() 这类 ...

  8. Java中的引用传递和值传递

    Java中的引用传递和值传递 关于Java的引用传递和值传递,在听了老师讲解后,还是没有弄清楚是怎么一回事,于是查了资料,所以在这里与大家分享,有不对的地方,欢迎大家留言. java中是没有指针的,j ...

  9. Java中没有引用传递只有值传递(在函数中)

    ◆传参的问题 引用类型(在函数调用中)的传参问题,是一个相当扯的问题.有些书上说是传值,有些书上说是传引用.搞得Java程序员都快成神经分裂了.所以,我们最后来谈一下“引用类型参数传递”的问题. 如下 ...

  10. 不可访问内存 Java四种引用包括强引用,软引用,弱引用,虚引用

    小结: 1.不可访问内存是指一组没有任何可访问指针指向的由计算机程序进行动态分配的内存块. 2.垃圾收集器能决定是否一个对象还是可访问的:任何被确定不可访问的对象将会被释放. https://zh.w ...

随机推荐

  1. Jetty的threadpool模块

    Jetty提供的线程池相关的模块,如下: threadpool threadpool-virtual,使用JDK 21提供的virtual threads. threadpool-virtual-pr ...

  2. 直播回顾 | 点击率提升400%,Ta是怎么做到的?

    Discovery第18期直播已于3月30日圆满结束,本期直播邀请天眼查做客直播间,从天眼查与华为Push用户增长服务合作历程切入,聚焦用户增长,分享提升应用活跃度和渠道ROI的经验与见解.一起来回顾 ...

  3. IE8页面失去焦点,动态删除element

    当页面失去焦点(切换到其他标签页 / 切换到其他软件),触发失焦事件,然后动态删除element 兼容IE8 if(window.ActiveXObject){ window.attachEvent( ...

  4. openGauss共享存储对接Ceph-单机openGauss-Ceph zhangxb2023-02-18

    openGauss + DSS + Ceph 部署操作步骤 本文档介绍单机版 openGauss+DSS+Ceph 集群部署方式.后续提供主备下的步骤. 服务器: Hostname IP 系统 规格 ...

  5. CentOS 6.3挂载读写NTFS分区(ntfs-3g) [亲测成功]

    CentOS 6.3挂载读写NTFS分区(ntfs-3g) CentOS不像Fedora,默认是没有自动挂载NTFS的,而它可以利用NTFS-3G来实现挂载及读写. NTFS-3G 是一个开源的软件, ...

  6. nginx重新整理——————http请求的11个阶段中的日志阶段[十九]

    前言 简单介绍一下access log 阶段. 正文 日志模块是 ngx_http_log_module,这个模块无法禁用,内置的. 结 上面是日志的用法.主要的一个内容是日志如果是变量的话,那么需要 ...

  7. hibernate4升级5带来的一些参数变化

    public String hqlToHibernate5(String hql) { String[] tmp = hql.split(" "); String hqlTmp = ...

  8. shell编程实现用户循环输入

    如果你想在Shell脚本中实现一个循环判断用户输入是否正确,并根据情况决定是否退出系统,可以使用一个无限循环(如while true)和条件语句来实现. 以下是一个示例代码,用于演示这种情况: #!/ ...

  9. Flink 作为现代数据仓库的统一引擎:Hive 集成生产就绪!

    在2020年,你的数据仓库和基础设施需要满足哪些需求? 我们总结了几下几点: 首先,当下的企业正快速转向更实时化的模式,这要求企业具备对线上流式数据进行低延迟处理的能力,以满足实时(real-time ...

  10. 官宣|Apache Flink 1.13.0 正式发布,流处理应用更加简单高效!

    简介: Flink 1.13.0 版本让流处理应用的使用像普通应用一样简单和自然,并且让用户可以更好地理解流作业的性能. ​翻译 | 高赟Review | 朱翥.马国维 Flink 1.13 发布了! ...