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

2024-09-07 07:04

本文主要是介绍Java中的强引用、软引用、弱引用和虚引用于JVM的垃圾回收机制,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

参考资料

  • 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。
  • 虚引用:不能直接访问对象内容,主要用于跟踪对象的垃圾回收情况。
    在这里插入图片描述

这篇关于Java中的强引用、软引用、弱引用和虚引用于JVM的垃圾回收机制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1144391

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

离心萃取机废旧磷酸铁锂电池回收工艺流程

在废旧磷酸铁锂电池的回收工艺流程中,离心萃取机主要应用于萃取除杂的步骤,以提高回收过程中有价金属(如锂)的纯度。以下是结合离心萃取机应用的废旧磷酸铁锂电池回收工艺流程: 电池拆解与预处理 拆解:将废旧磷酸铁锂电池进行拆解,分离出电池壳、正负极片、隔膜等部分。破碎与筛分:将正负极片进行破碎处理,并通过筛分将不同粒径的物料分开,以便后续处理。 浸出与溶解 浸出:采用适当的浸出工艺(如二段式逆

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听