首页 > 编程语言 >Java引用类型解析:掌握强引用、软引用、弱引用和幻象引用的妙用

Java引用类型解析:掌握强引用、软引用、弱引用和幻象引用的妙用

时间:2024-03-03 09:01:29浏览次数:32  
标签:Java 对象 object 回收 幻象 引用 垃圾

 

概述:Java中的引用分为强引用、软引用、弱引用和幻象引用。强引用是最常见的,不会被垃圾回收;软引用在内存不足时才被回收;弱引用在下一次垃圾回收时回收;幻象引用用于检测对象是否已被回收。它们各自适用于不同场景,帮助开发者更灵活地管理对象生命周期,避免内存泄漏。

在Java中,引用是一种机制,用于在进行垃圾回收时确定对象是否可被回收。Java中的引用主要分为强引用、软引用、弱引用和幻象引用。以下是它们的详细讲解,包括应用场景和注意事项。

1. 强引用(Strong Reference):

强引用是最普通的引用类型。如果一个对象具有强引用,垃圾回收器绝不会回收它,即使内存不足。

应用场景:

  • 对象的生命周期需要与引用保持一致。
  • 大多数对象默认是强引用。

注意事项:

  • 可能导致内存泄漏,因为强引用的对象只有在显式地被设置为null时才能被垃圾回收。

实例代码:

public class StrongReferenceExample {
    public static void main(String[] args) {
        // 创建强引用
        Object object = new Object();
        
        // object仍然可访问
        System.out.println(object);
        
        // 设置为null后,object可能被垃圾回收
        object = null;
    }
}

2. 软引用(Soft Reference):

软引用在系统即将发生内存溢出之前,会被垃圾回收器回收。

应用场景:

  • 对于可有可无的缓存数据。

注意事项:

  • 当系统内存充足时,软引用不会被回收,但在内存不足时会被垃圾回收。

实例代码:

import java.lang.ref.SoftReference;

public class SoftReferenceExample {
    public static void main(String[] args) {
        // 创建软引用
        SoftReference<Object> softReference = new SoftReference<>(new Object());
        
        // 获取软引用对象
        Object object = softReference.get();
        
        // object仍然可访问
        System.out.println(object);
        
        // 在内存不足时,softReference可能被垃圾回收
    }
}

3. 弱引用(Weak Reference):

弱引用在下一次垃圾回收时就会被回收,不考虑内存是否充足。

应用场景:

  • 用于实现对象缓存,但不希望对象缓存在内存中太久。

注意事项:

  • 当发生垃圾回收时,弱引用对象会被立即回收。

实例代码:

import java.lang.ref.WeakReference;

public class WeakReferenceExample {
    public static void main(String[] args) {
        // 创建弱引用
        WeakReference<Object> weakReference = new WeakReference<>(new Object());
        
        // 获取弱引用对象
        Object object = weakReference.get();
        
        // object仍然可访问
        
        // 强制触发垃圾回收
        System.gc();
        
        // 在垃圾回收后,weakReference可能被回收
    }
}

4. 幻象引用(Phantom Reference):

幻象引用用于检测对象是否已经从内存中删除。

应用场景:

  • 通常与ReferenceQueue一起使用,用于在对象被垃圾回收前执行一些清理操作。

注意事项:

  • 幻象引用的get方法始终返回null。
  • 必须使用ReferenceQueue来配合使用,以获知对象何时被回收。

实例代码:

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

public class PhantomReferenceExample {
    public static void main(String[] args) {
        ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
        
        // 创建幻象引用
        PhantomReference<Object> phantomReference = new PhantomReference<>(new Object(), referenceQueue);
        
        // 获取幻象引用对象,始终返回null
        Object object = phantomReference.get();
        
        // 在垃圾回收后,phantomReference会被放入referenceQueue
        System.gc();
        
        // 从referenceQueue中获取被回收的引用
        PhantomReference<Object> collectedReference = (PhantomReference<Object>) referenceQueue.poll();
    }
}

通过使用这些引用类型,可以更灵活地管理对象的生命周期,同时避免内存泄漏和提高系统性能。

 

标签:Java,对象,object,回收,幻象,引用,垃圾
From: https://www.cnblogs.com/hanbing81868164/p/18049588

相关文章

  • JavaWeb_mac_env
    maven安装brew安装wgetbrewinstallwgetbrewcleanup--prune=all //删除所有安装缓存下载mavenwgethttps://dlcdn.apache.org/maven/maven-3/3.9.6/binaries/apache-maven-3.9.6-bin.tar.gz或者curl-Ohttps://dlcdn.apache.org/maven/maven-3/3.9.6/binaries/apache......
  • java Flappy Bird小游戏二次开发
    引言FlappyBird是一款广为人知的经典小游戏,以其简单的操作方式和高难度挑战吸引了全球数百万玩家。游戏的核心机制非常直接——玩家通过点击屏幕使小鸟飞翔,避免碰撞到上下移动的管道,同时尽可能地飞行得更远。这种看似简单的游戏设计隐藏了深层的挑战性和上瘾性,让人不禁一试再试......
  • Java学习笔记——第三天
    流程控制程序中最经典的三种执行顺序顺序结构:自上而下地执行代码,最普通的执行顺序。分支结构:根据条件,选择对应代码执行。循环结构:控制某段代码重复执行。分支结构if分支if分支的作用根据条件(真或假)来决定执不执行某段代码或执行哪段代码。if分支应用场景需要根据不同......
  • 为什么要使用Java SPI机制
    JavaSPI(ServiceProviderInterface)最早是在JavaSE6中被引入的,作为一种标准的、用于在运行时发现和加载服务提供者插件的标准机制。以前的程序猿实现JDBC连接数据库都会自己写工具类加载不同厂商的驱动来实现数据库操作,但是随着JDBC4.0之后采用了JavaSPI机制,这部分工作就变的......
  • C++第六节课 引用变量 指针的升级版
    #include<iostream>usingnamespacestd;//C++的引用是C指针的升级可以提高代码的稳定性和健壮性//const修饰的引用是常引用//函数传参实参向形参进行传递默认是值的传递这个是值的一个副本两个互不影响intadd(constint&a,constint&b){///a++;避......
  • Java流程控制
    Scanner对象Java提供了一个工具类,可以获取用户的输入。java.util.Scanner是Java5的新特征。基本语法:Scannerscanner=newScanner(System.in);使用后关闭:scanner.close();通过Scanner类的next()与nextLine()方法获取输入的字符串,在读取前一般需要使用hasNext()与hasNex......
  • Java基础
    Java基础1、JVMvsJREvsJDK思路:可以从他们之间的关系回答,从小到大进行介绍它们之间的关系和不同,比如jvm<jre<jdk答案:JVM是运行Java字节码的虚拟机。JVM会根据不同的系统进行特定的设计(Windows、Linux、MacOS),目的是在不同的操作系统上使用相同的字节码可以得到相......
  • Java消息服务JMS
    一、JMS规范JMS是Java消息服务(JavaMessageService)应用程序接口的简写,是一个Java平台中关于面向消息中间件(MOM)的API,它为标准消息协议和消息服务提供了一组通用接口,包括创建、发送、读取消息等。用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。Java消息服务是一......
  • Java Pattern和Matcher处理正则表达式的用法
    转自:https://zhuanlan.zhihu.com/p/626497347 结论:Pattern与Matcher一起合作.Matcher类提供了对正则表达式的分组支持,以及对正则表达式的多次匹配支持.单独用Pattern只能使用Pattern.matches(Stringregex,CharSequenceinput)一种最基础最简单的匹配。java正则表达式通过ja......
  • Java高频面试题
    Redis一、Redis的使用场景①缓存 ②分布式锁 ③限流 ④购物车 ⑤Token存储 ⑥点赞关注 ⑦短信验证码存储 ⑧分布式Session ⑨发布订阅 ⑩排行榜1、缓存 热点数据(经常查询,但不修改和删除)首选redis,性能高。 2、分布式锁注:锁,即在多线程环境下,对共享资......