Java中的强引用、软引用、弱引用和虚引用于JVM的垃圾回收机制

news2024/9/21 1:28:58

参考资料

  • https://juejin.cn/post/7123853933801373733

在 Java 中,引用类型分为四种:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)和虚引用(Phantom Reference)。这些引用类型的主要区别在于它们如何与垃圾回收器(GC)进行交互。

1. 强引用(Strong Reference)

定义:强引用是 Java 中最常见的引用类型。只要一个对象有强引用存在,垃圾回收器就不会回收这个对象。

示例

String strongRef = new String("Hello, World!");

解释

  • 在这段代码中,strongRef 是一个指向 String 对象的强引用。只要 strongRef 变量存在,并指向 String 对象,垃圾回收器就不会回收它。

2. 软引用(Soft Reference)

定义:软引用是一个在内存不足时才会被垃圾回收的引用。它通常用于实现缓存,当内存不足时,垃圾回收器会回收这些被软引用指向的对象。

示例

import java.lang.ref.SoftReference;

String str = new String("This is a soft reference example");
SoftReference<String> softRef = new SoftReference<>(str);

// 使强引用失效
str = null;

解释

  • softRef 是指向 String 对象的软引用。
  • 一旦 str 置为 null,强引用消失,该对象仅通过 softRef 保持可达状态。
  • 当 JVM 发现内存不足时,它可能会回收 softRef 指向的对象。

3. 弱引用(Weak Reference)

定义:弱引用是一个比软引用更弱的引用类型。弱引用的对象在垃圾回收过程中,只要发现弱引用,不管当前内存是否足够,都会被回收。

示例

import java.lang.ref.WeakReference;

String str = new String("This is a weak reference example");
WeakReference<String> weakRef = new WeakReference<>(str);

// 使强引用失效
str = null;

解释

  • weakRef 是指向 String 对象的弱引用。
  • 一旦 str 置为 null,强引用消失,该对象仅通过 weakRef 保持可达状态。
  • 在下次垃圾回收时,无论内存是否充足,垃圾回收器都会回收 weakRef 指向的对象。

4. 虚引用(Phantom Reference)

定义:虚引用(或幻影引用)是最弱的一种引用类型。一个对象不能通过虚引用获得其引用对象。虚引用主要用于跟踪对象被垃圾回收的过程。当一个对象只剩下虚引用时,在下一次垃圾回收时会被回收。同时,虚引用必须和引用队列(ReferenceQueue)一起使用。

示例

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;

String str = new String("This is a phantom reference example");
ReferenceQueue<String> refQueue = new ReferenceQueue<>();
PhantomReference<String> phantomRef = new PhantomReference<>(str, refQueue);

// 使强引用失效
str = null;

// 使用队列来检查虚引用对象是否被回收
if (phantomRef.isEnqueued()) {
    System.out.println("Object is ready to be reclaimed by the garbage collector.");
}

解释

  • phantomRef 是指向 String 对象的虚引用,refQueue 是一个引用队列。
  • 一旦 str 被置为 null,对象仅通过 phantomRef 虚引用保持“存在”,但实际上已经无法通过该引用访问对象。
  • 在对象被垃圾回收后,phantomRef 会被加入到 refQueue 中,程序可以通过 refQueue 得知对象已被回收。

ReferenceQueue 是 Java 中提供的一个队列,用于与软引用(SoftReference)、弱引用(WeakReference)、和虚引用(PhantomReference)等引用类型一起使用,以便在对象被垃圾回收时得到通知或做相应的清理工作。

ReferenceQueue 的作用

  1. 跟踪被回收的对象ReferenceQueue 用来保存被垃圾回收器标记为可回收的引用对象。当一个对象被垃圾回收后,如果该对象的引用(软引用、弱引用或虚引用)关联了一个 ReferenceQueue,那么这个引用会被加入到 ReferenceQueue 中。

  2. 用于清理和资源管理:通过 ReferenceQueue,程序可以在对象被回收时执行某些清理操作,例如释放外部资源、关闭文件等。特别是虚引用(PhantomReference)必须和 ReferenceQueue 一起使用,因为虚引用的主要目的是帮助检测对象的垃圾回收状态。

ReferenceQueue 的使用场景

  • 缓存管理:结合软引用和弱引用使用,在内存不足或对象无强引用的情况下,对象被垃圾回收器回收并加入到 ReferenceQueue,可用于从缓存中移除无用数据。

  • 对象的生命周期管理:对于需要明确知道对象何时被垃圾回收的场景,可以使用虚引用和 ReferenceQueue,以便在对象被回收时执行某些特殊的清理操作。

示例:使用 ReferenceQueue

下面是一个使用 ReferenceQueue 和弱引用的简单示例:

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;

public class ReferenceQueueExample {
    public static void main(String[] args) {
        // 创建一个引用队列
        ReferenceQueue<String> refQueue = new ReferenceQueue<>();
        
        // 创建一个字符串对象并将其封装在一个弱引用中,同时关联引用队列
        String str = new String("Hello, ReferenceQueue");
        WeakReference<String> weakRef = new WeakReference<>(str, refQueue);
        
        // 清除强引用
        str = null;
        
        // 手动调用垃圾回收器(这只是一个提示,GC 可能不会立即执行)
        System.gc();
        
        // 检查引用队列中是否有被回收的引用
        Reference<? extends String> refFromQueue = refQueue.poll();
        if (refFromQueue != null) {
            System.out.println("The weakly referenced object has been garbage collected and the reference is in the queue.");
        } else {
            System.out.println("The object has not been garbage collected yet.");
        }
    }
}

代码解释

  1. 创建引用队列ReferenceQueue<String> refQueue = new ReferenceQueue<>(); 创建了一个 ReferenceQueue 对象,用于保存被垃圾回收的引用。

  2. 创建弱引用WeakReference<String> weakRef = new WeakReference<>(str, refQueue); 创建一个指向 str 的弱引用,并将其与 refQueue 关联。

  3. 清除强引用:通过 str = null; 清除对对象的强引用,使得该对象仅被弱引用所引用。

  4. 手动触发 GC:调用 System.gc(); 提示垃圾回收器运行。请注意,这只是一个提示,垃圾回收器不一定会立即执行。

  5. 检查引用队列:通过 refQueue.poll() 检查引用队列中是否有被回收的引用,如果返回非 null 值,则表示对象已经被回收。

总结

  • 强引用:最常见的引用类型,不会被垃圾回收。
  • 软引用:在内存不足时会被回收,适用于缓存。
  • 弱引用:在垃圾回收时会被回收,适用于对内存敏感的数据结构,如 WeakHashMap。
  • 虚引用:不能直接访问对象内容,主要用于跟踪对象的垃圾回收情况。
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2111792.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

5G移动网络运维实验(训)室解决方案

随着第五代移动通信技术&#xff08;5G&#xff09;的快速普及和工业互联网的迅猛发展&#xff0c;全球制造业正面临着前所未有的深刻变革。5G技术凭借其超高的传输速率、极低的延迟以及大规模的连接能力&#xff0c;为工业自动化、智能制造等领域带来了革命性的技术支持。为了…

【免费分享】GIS开发面试题(流程+自我介绍+基础篇+Openlayermapbox)

本篇文章针对GIS应届生就业方向及面试困惑问题进行了收集整理&#xff0c;并列出了关于GIS开发面试中常见的问题&#xff08;含答案&#xff09;。 “ 包括以下内容 前言 简介 面试之前 面试流程 自我介绍-AI 基础篇 1、GIS八股文基础篇 2、Openlayers图形绘制 3、倾…

2-1 opencv实战进阶系列 阈值编辑器

目录 一、不说废话&#xff0c;先上现象 二、前言 三、方法详解 四、贴出完整代码 一、不说废话&#xff0c;先上现象 二、前言 对图像的处理中&#xff0c;设置合适的掩膜、寻找多边形、颜色追踪等方法都需要预先设置好颜色的上阈值和下阈值&#xff0c;来从原图中分割出…

蔚来发布新财报,亏损收窄,营收同比增长98.9%!

KlipC报道&#xff1a;9月5日&#xff0c;蔚来发布2024年二季度财报&#xff0c;财报显示&#xff0c;营收174.5亿元&#xff0c;同比增长98.9%&#xff0c;环比增长76.1%&#xff1b;交付量5.74万台&#xff0c;同比增长143.9%&#xff0c;环比增长90.9%&#xff1b;营收和交付…

Yolov5实现目标检测——调用官方权重进行检测

本文为为&#x1f517;365天深度学习训练营内部文章 原作者&#xff1a;K同学啊 一 安装源码 开源网址&#xff1a;GitHub - ultralytics/yolov5: YOLOv5 &#x1f680; in PyTorch > ONNX > CoreML > TFLite ​ 二 安装所需环境 安装环境依赖包&#xff0c;进入项目…

探索Mem0:下一代人工智能与机器学习内存管理基础设施(二)Mem0+Ollama 部署运行

探索Mem0:下一代人工智能与机器学习内存管理基础设施(二) Mem 0(发音为“mem-zero”)通过智能记忆层增强AI助手和代理,实现个性化的AI交互。Mem 0会记住用户偏好,适应个人需求,并随着时间的推移不断改进,使其成为客户支持聊天机器人,AI助手和自治系统的理想选择。 …

[Mdp] lc198. 打家劫舍(记忆化搜索+dp)

文章目录 1. 题目来源2. 题目解析 1. 题目来源 链接&#xff1a;198. 打家劫舍 前置&#xff1a; [每日一题] 146. 打家劫舍(数组、动态规划、巧妙解法) 2. 题目解析 记忆化搜索可以处理&#xff0c;是自顶向下进行枚举的&#xff0c;属于 递归。 动态规划&#xff0c;属于…

Nuxt3服务端渲染项目简单搭建

目录 1.准备阶段 2.创建项目 3.安装需要的模块 1&#xff09;安装ArcoDesign/ElementPlus 2&#xff09;安装tailwindcss 4.目录结构 5.网站TDK设置 本篇文章相关的官方网站&#xff1a; 1.nuxt3&#xff1a;Nuxt 中文站 - 直观的Web框架 Nuxt3文档 Nuxt 2.vue3&#xf…

fpga系列 HDL:Vivado 安装usb cable驱动

安装usb cable驱动 安装cable_drivers:在data\xicom\cable_drivers\nt64\dlc10_win7目录 安装digilent

数据分析-12-多个时间序列数据的时间戳对齐以及不同的方式补点

参考python时间序列数据的对齐和数据库的分批查询 1 问题场景与分析 1.1 场景 在医院的ICU里,须要持续观察病人的各项生命指标。这些指标的采集频率每每是不一样的(例如有些指标隔几秒采集一个,有些几个小时采集一个,有些一天采集一个),并且有些是按期的,有些是不按期的…

SpringMVC基于注解使用:上传下载

01-文件下载 基于servlet api的文件下载 注意一点content-disposition是以文件下载的方式打开意思是客户端地址栏不会改变&#xff0c; 如果注销了那句话就会跳转到下载图片的图片里面去&#xff0c;就在网页中显示了 基于spring ResponseEntity的文件下载 不支持缓冲区 一次…

使用 OpenCV 和 NumPy 进行图像处理:HSV 范围筛选实现PS抠图效果

使用 OpenCV 和 NumPy 进行图像处理&#xff1a;HSV 范围筛选实现PS抠图效果 在计算机视觉和图像处理领域&#xff0c;OpenCV 是一个非常强大的库&#xff0c;能够帮助我们执行各种图像操作。在这篇博客中&#xff0c;我们将通过一个简单的示例演示如何使用 OpenCV 和 NumPy 来…

时序预测|变分模态分解-双向时域卷积-双向门控单元-注意力机制多变量时间序列预测VMD-BiTCN-BiGRU-Attention

时序预测|变分模态分解-双向时域卷积-双向门控单元-注意力机制多变量时间序列预测VMD-BiTCN-BiGRU-Attention 文章目录 一、基本原理1. 变分模态分解&#xff08;VMD&#xff09;2. 双向时域卷积&#xff08;BiTCN&#xff09;3. 双向门控单元&#xff08;BiGRU&#xff09;4. …

基于sklearn的机器学习 — KNN

k-nearest neighbors&#xff08;KNN&#xff09;算法是监督机器学习中最简单但最常用的算法之一。 KNN通常被认为是一种惰性的学习算法&#xff0c;从技术上讲&#xff0c;它只是存储训练数据集&#xff0c;而不经历训练阶段。 KNN的原理是将新样本的特征与数据集中现有样本…

设计之道:ORM、DAO、Service与三层架构的规范探索

引言&#xff1a; 实际开发中&#xff0c;遵守一定的开发规范&#xff0c;不仅可以提高开发效率&#xff0c;还可以提高项目的后续维护性以及项目的扩展性&#xff1b;了解一下本博客的项目设计规范&#xff0c;对项目开发很有意义 一、ORM思想 ORM&#xff08;Object-Relation…

小琳AI课堂:大模型的发展历程:从创新到挑战

大家好&#xff0c;这里是小琳AI课堂。今天我们来聊聊大模型的发展历程&#xff0c;这是一段充满创新与挑战的故事。&#x1f680; 让我们追溯到20世纪50年代&#xff0c;那时计算机科学和人工智能还处于萌芽阶段。 早期探索&#xff08;1950s-1970s&#xff09; 早期探索是大…

网络安全应急响应技术原理与应用

网络安全应急响应概述 概念 为应对网络安全事件&#xff0c;相关人员或组织机构对网络安全事件进行监测、预警、分析、响应和恢复等工作 网络安全应急响应组织建立与工作机制 网络安全应急响应预案内容与类型 常见网络安全应急事件场景与处理流程 应急演练&#xff1a;对假定…

iOS——APP启动流程

APP启动 APP启动主要分为两个阶段&#xff1a;pre-main和main之后&#xff0c;而APP的启动优化也主要是在这两个阶段进行的。 main之后的优化&#xff1a;1. 减少不必要的任务&#xff0c;2.必要的任务延迟执行&#xff0c;例如放在控制器界面等等。 APP启动的大致过程&#…

腾讯云 Spring Boot 安装 SSL 证书

linux和windows下&#xff0c;因为有ngxin&#xff0c;所以安装ssl证书都感觉比较容易&#xff0c;毕竟通过代理方式能够胜任大多数的https安全问题。 但是有些情况下&#xff0c;ngxin可能无法安装什么的&#xff0c;可能需要在spring boot下直接安装ssl&#xff0c;咋办&…

【漏洞复现】某客圈子社区小程序审计(0day)

0x00 前言 █ 纸上得来终觉浅,绝知此事要躬行 █ Fofa:"/static/index/js/jweixin-1.2.0.js"该程序使用ThinkPHP 6.0.12作为框架,所以直接审计控制器即可.其Thinkphp版本较高,SQL注入不太可能,所以直接寻找其他洞. 0x01 前台任意文件读取+SSRF 在 /app/api/c…