62.Java中几种不同的引用-强软弱虚

2024-05-29 16:38
文章标签 java 引用 几种 不同 62 软弱

本文主要是介绍62.Java中几种不同的引用-强软弱虚,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 1.`Java`中几种不同的引用-强软弱虚概述
    • 1.1 强引用
    • 1.2 软引用
    • 1.3 弱引用
    • 1.4 虚引用

1.Java中几种不同的引用-强软弱虚概述

  1. java中的引用分为4种,强引用、软引用、弱引用、虚引用,引用强度依次逐渐减弱,都继承自Reference
    在这里插入图片描述
  2. 四种引用概述
    强引用:最传统的引用的定义,在开发中99%都是使用的强引用。即类似“Object obj = new Object()”这种引用关系。无论任何情况下,只要强引用的关系存在,垃圾收集器就永远不会回收掉被引用的对象。
    软引用:在系统将要发生内存溢出之前,将会把这些被软引用的对象列入回收范围之中进行回收。如果这次回收之后还没有足够的内存,才会抛出内存溢出异常。概括为:内存不足即回收。
    弱引用:当垃圾收集的时候,无论内存空间是否足够,被弱引用关联的对象就会被回收掉。概括为:发现即回收。
    虚引用:虚引用不会影响对象生存的时间。使用虚引用的目的是为了能在对象被垃圾回收器回收时收到一个系统通知。概括为:对象回收跟踪。
    在这里插入图片描述

1.1 强引用

在这里插入图片描述
强引用特点:
在这里插入图片描述

1.2 软引用

当内存足够时不会回收软引用对象,当内存不足时,才会回收软引用对象。
在这里插入图片描述
软引用使用:使用java.lang.ref.SoftReference类来实现软引用。
在这里插入图片描述
例子:

public class SoftReferenceTest {public static class User {public User(int id, String name) {this.id = id;this.name = name;}public int id;public String name;@Overridepublic String toString() {return "[id=" + id + ", name=" + name + "] ";}}public static void main(String[] args) {//创建对象,建立软引用
//        SoftReference<User> userSoftRef = new SoftReference<User>(new User(1, "songhk"));//上面的一行代码,等价于如下的三行代码User u1 = new User(1,"songhk");SoftReference<User> userSoftRef = new SoftReference<User>(u1);u1 = null;//取消强引用//从软引用中重新获得强引用对象System.out.println(userSoftRef.get()); // 拿到创建的User对象System.gc();System.out.println("After GC:");
//        //垃圾回收之后获得软引用中的对象System.out.println(userSoftRef.get());//如果堆空间内存足够,则不会回收软引用的可达对象。否则,会回收这个对象,输出null。
//try {//让系统认为内存资源紧张、不够
//            byte[] b = new byte[1024 * 1024 * 7];byte[] b = new byte[1024 * 7168 - 635 * 1024];} catch (Throwable e) {e.printStackTrace();} finally {//再次从软引用中获取数据System.out.println(userSoftRef.get());//在报OOM之前,垃圾回收器会回收软引用的可达对象。}}
}

1.3 弱引用

只被弱引用关联的对象在垃圾回收的时候就会被回收。
软引用、弱引用非常适合来保存那些可有可无的缓存数据。当内存足够的时候,这些缓存数据可以存着很长的时间;当内存不足的时候,这些缓存数据就可以被回收,不会导致内存溢出。
在这里插入图片描述
使用方法:
在这里插入图片描述
软引用与弱引用的不同:当进行GC的时候,需要通过算法来检查是否回收软引用对象(判断内存是否足够),而对于弱引用对象,GC总是进行回收。

例子:

public class WeakReferenceTest {public static class User {public User(int id, String name) {this.id = id;this.name = name;}public int id;public String name;@Overridepublic String toString() {return "[id=" + id + ", name=" + name + "] ";}}public static void main(String[] args) {//构造了弱引用WeakReference<User> userWeakRef = new WeakReference<User>(new User(1, "songhk"));//从弱引用中重新获取对象System.out.println(userWeakRef.get());System.gc();// 不管当前内存空间足够与否,都会回收它的内存System.out.println("After GC:");//重新尝试从弱引用中获取对象System.out.println(userWeakRef.get());}
}

1.4 虚引用

一个对象是否存在虚引用,完全不会影响对象的生命周期。为一个对象设置虚引用关联的唯一目的就是跟踪垃圾回收过程。比如,在这个对象被回收的时候,收到一个系统通知。
在这里插入图片描述
虚引用必须与引用队列一起使用。当垃圾回收器回收一个对象时,如果发现它还有虚引用,就会在回收对象之后,将虚引用加入到引用队列中,以通知应用程序对象的回收情况。
在这里插入图片描述
例子:

public class PhantomReferenceTest {public static PhantomReferenceTest obj;//当前类对象的声明static ReferenceQueue<PhantomReferenceTest> phantomQueue = null;//引用队列public static class CheckRefQueue extends Thread {@Overridepublic void run() {while (true) {if (phantomQueue != null) {PhantomReference<PhantomReferenceTest> objt = null;try {objt = (PhantomReference<PhantomReferenceTest>) phantomQueue.remove();} catch (InterruptedException e) {e.printStackTrace();}if (objt != null) {System.out.println("追踪垃圾回收过程:PhantomReferenceTest实例被GC了");}}}}}@Overrideprotected void finalize() throws Throwable { //finalize()方法只能被调用一次!super.finalize();System.out.println("调用当前类的finalize()方法");obj = this;}public static void main(String[] args) {Thread t = new CheckRefQueue();t.setDaemon(true);//设置为守护线程:当程序中没有非守护线程时,守护线程也就执行结束。t.start();phantomQueue = new ReferenceQueue<PhantomReferenceTest>();obj = new PhantomReferenceTest();//构造了 PhantomReferenceTest 对象的虚引用,并指定了引用队列PhantomReference<PhantomReferenceTest> phantomRef = new PhantomReference<PhantomReferenceTest>(obj, phantomQueue);try {//不可获取虚引用中的对象System.out.println(phantomRef.get());//将强引用去除obj = null;//第一次进行GC,由于对象可复活,GC无法回收该对象System.gc();Thread.sleep(1000);if (obj == null) {System.out.println("obj 是 null");} else {System.out.println("obj 可用");}System.out.println("第 2 次 gc");obj = null;System.gc(); //一旦将obj对象回收,就会将此虚引用存放到引用队列中。Thread.sleep(1000);if (obj == null) {System.out.println("obj 是 null");} else {System.out.println("obj 可用");}} catch (InterruptedException e) {e.printStackTrace();}}
}

更多JVM文章请访问我的JVM专栏:
https://blog.csdn.net/u011069294/category_10113093.html

这篇关于62.Java中几种不同的引用-强软弱虚的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

SpringBoot全局域名替换的实现

《SpringBoot全局域名替换的实现》本文主要介绍了SpringBoot全局域名替换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录 项目结构⚙️ 配置文件application.yml️ 配置类AppProperties.Ja

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

JavaScript中的高级调试方法全攻略指南

《JavaScript中的高级调试方法全攻略指南》什么是高级JavaScript调试技巧,它比console.log有何优势,如何使用断点调试定位问题,通过本文,我们将深入解答这些问题,带您从理论到实... 目录观点与案例结合观点1观点2观点3观点4观点5高级调试技巧详解实战案例断点调试:定位变量错误性能分

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

Java使用jar命令配置服务器端口的完整指南

《Java使用jar命令配置服务器端口的完整指南》本文将详细介绍如何使用java-jar命令启动应用,并重点讲解如何配置服务器端口,同时提供一个实用的Web工具来简化这一过程,希望对大家有所帮助... 目录1. Java Jar文件简介1.1 什么是Jar文件1.2 创建可执行Jar文件2. 使用java

SpringBoot实现不同接口指定上传文件大小的具体步骤

《SpringBoot实现不同接口指定上传文件大小的具体步骤》:本文主要介绍在SpringBoot中通过自定义注解、AOP拦截和配置文件实现不同接口上传文件大小限制的方法,强调需设置全局阈值远大于... 目录一  springboot实现不同接口指定文件大小1.1 思路说明1.2 工程启动说明二 具体实施2

Java实现在Word文档中添加文本水印和图片水印的操作指南

《Java实现在Word文档中添加文本水印和图片水印的操作指南》在当今数字时代,文档的自动化处理与安全防护变得尤为重要,无论是为了保护版权、推广品牌,还是为了在文档中加入特定的标识,为Word文档添加... 目录引言Spire.Doc for Java:高效Word文档处理的利器代码实战:使用Java为Wo

SpringBoot日志级别与日志分组详解

《SpringBoot日志级别与日志分组详解》文章介绍了日志级别(ALL至OFF)及其作用,说明SpringBoot默认日志级别为INFO,可通过application.properties调整全局或... 目录日志级别1、级别内容2、调整日志级别调整默认日志级别调整指定类的日志级别项目开发过程中,利用日志

Java中的抽象类与abstract 关键字使用详解

《Java中的抽象类与abstract关键字使用详解》:本文主要介绍Java中的抽象类与abstract关键字使用详解,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、抽象类的概念二、使用 abstract2.1 修饰类 => 抽象类2.2 修饰方法 => 抽象方法,没有