强引用、软引用、弱引用、虚引用有什么区别?

简介: 本文主要介绍强引用、软引用、弱引用、虚引用

强引用、软引用、弱引用、虚引用 · 语雀 (yuque.com)

自 JDK1.2 开始,Java 提供了 4 种引用关系,以表示引用和实例对象的关系。

强引用“一直存活着”

强引用,就是我们最常见的普通对象引用。

只要强引用还存在,垃圾收集器永远不会回收掉被引用的实例对象。

Object o = new Object();

软引用“有 n 次活的机会”

在系统将要发生内存溢出异常之前,垃圾收集器会把只被软引用关联着的实例对象进行回收,如果这次回收还没有足够的内存,才会抛出内存溢出异常(OutOfMemoryError)。


软引用通常用来实现内存敏感的缓存:

  • 如果还有空闲内存,就可以暂时保留缓存;
  • 如果内存不足,则清理掉缓存;

这样就保证了使用缓存的同时,不会耗尽内存。

SoftReference<Object> softO = new SoftReference<>(new Object());

弱引用“回收就会死亡”

被弱引用关联着的实例对象只能生存到下一次垃圾收集发生之前,当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的实例对象。


弱引用可以用来构建一种没有特定约束的关系,比如,维护一种非强制性的映射关系,如果试图获取时对象还在,就使用它,否则重现实例化。弱引用同样是很多缓存实现的选择。

WeakReference<Object> weakO = new WeakReference(new Object());

虚引用“随时可能被回收”

虚引用也称为“幽灵引用”或者“幻影引用”,虚引用是最弱的一种引用关系。

  • 在Java 8以及之前的版本中,在虚引用回收后,虚引用指向的对象才会回收。
  • 在Java 9以及更新的版本中,虚引用不会对对象的生存时间产生任何影响。

无法通过虚引用来获取一个实例对象。

虚引用主要用来跟踪对象被垃圾回收的活动,回收对象关联的资源。

在Java 8以及之前的版本中,当垃圾收集器准备回收一个实例对象时,如果发现它还有虚引用,就会在回收实例对象之前,把这个虚引用加入到与之关联的引用队列中。程序如果发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动,然后断开虚引用对象的引用,虚引用被回收或者不可达,虚引用指向的对象才会回收。

Object counter = new Object();
ReferenceQueue refQueue = new ReferenceQueue<>();
PhantomReference<Object> p = new PhantomReference<>(counter, refQueue);
counter = null;
System.gc();
try {
    // Remove 是一个阻塞方法,可以指定 timeout,或者选择一直阻塞
    Reference<Object> ref = refQueue.remove(1000L);
    if (ref != null) {
        // do something
        
        ref = null;
    }
} catch (InterruptedException e) {
    // Handle it
}

参考资料

第4讲 | 强引用、软引用、弱引用、幻象引用有什么区别?

ThreadLocal 原理分析及内存泄漏演示

相关文章
|
C语言
C语言位运算符详解
C语言位运算符详解
618 0
|
存储 SQL 分布式计算
对象存储解决方案 开源对象存储平台 自建对象存储解决方案
对象存储解决方案 开源对象存储平台 自建对象存储解决方案
735 4
|
数据采集 JavaScript 前端开发
利用无头浏览器进行APP提取数据的技术与实践
利用无头浏览器进行APP提取数据的技术与实践
|
消息中间件 数据采集 安全
Python教程:深入理解 Python multiprocessing.Queue
在 Python 编程中,多进程编程是利用计算机多核心资源的重要手段之一。然而,多进程之间的通信却是一个相对复杂的问题。在本文中,我们将深入探讨 Python 中的 multiprocessing.Queue 模块,它为多进程间的通信提供了便捷而高效的解决方案。
375 5
|
人工智能 API 数据安全/隐私保护
云效+SAE,5分钟搞定一个AI 应用的开发和部署
本实验将带你体验云效应用交付平台AppStack+Serverless 应用交付引擎 SAE,从应用视角,完成一个AI聊天助手的高效交付。
629 0
java使用Files.walkFileTree统计文件夹下的文件夹和文件数量
java使用Files.walkFileTree统计文件夹下的文件夹和文件数量
242 0
|
监控 小程序 开发者
【小程序质量提优解决方案】(一)页面不存在
【小程序质量提优解决方案】(一)页面不存在
705 11
|
SQL 关系型数据库 数据库
Flink CDC数据同步问题之数据同步很慢如何解决
Flink CDC数据同步是指利用Flink CDC实现不同数据源之间的实时数据同步任务;本合集旨在提供Flink CDC数据同步的操作指南、性能优化建议和常见问题处理,助力用户高效实施数据同步。
|
API 文件存储
使用Streamlit创建AutoGen用户界面
AutoGen作为一个最大化LLM(如GPT-4)能力的框架而脱颖而出。由微软研究院开发的AutoGen通过提供一种自动化、优化和编排工作流的方法,简化了复杂的、基于多代理llm的应用程序的创建。我们在以前的文章中也有过介绍,你可以与许多GPT交谈,并且GPT和GPT之间也可以互相交谈。每个GPT都是它自己的“代理”,并在总体业务流程中扮演特殊角色。但是AutoGen是用命令行模式进行交互的,这对我们的输入来说非常不方便,所以这次我们来对其进行改造,使用Streamlit创建一个web界面,这样可以让我们更好的与其交互。
672 1
|
存储 算法 Oracle
雪花算法基本原理与实现
雪花算法基本原理与实现
516 0