Java 四种引用

news2024/10/5 4:28:26

目录

四种引用是怎么来的? 

SoftReference

 WeakReference

 PhantomReference


四种引用是怎么来的? 

        其实最开始的引用是用来判断一个对象是否存活的, 也就是说, 如果从GC Roots中的一个root出发, 如果存在一个引用链, 与这个对象有关联, 那么就说明这个对象是存活的. 

 但是有一点需要确认的是, 如果只是基于有没有被引用两种状态, 是不是过于狭隘了, 例如我们想要描述一些对象: 当空间足够的时候, 可以保留在内存之中, 如果内存不够了, 再将其进行垃圾回收, 其实很多场景就有这种需求. 

        在jdk1.2之中对引用的类型进行了扩充, 将引用扩充为了四个引用, 分别为: 

  • 强引用, 也就是直接new出来的引用, 例如 Object obj = new Object(); 只要这种强引用的关系存在, 那么 垃圾收集器就永远都不会收集它
  • 软引用, 这个用来描述那些非必须对象, 引用强度比软引用更弱一些.  被软引用关联的对象, 在系统发生内存溢出之前, 会把这类对象列进二次回收的范围之中, 如果回收之后, 还是没有足够的内存, 那么就会爆出内存溢出的异常. 
  • 弱引用, 描述那些非必须的, 缺了它也不会对系统造成什么影响, 被弱引用关联的对象, 只能生存到下一次垃圾回收之前, 无论是否内存足够, 都会被回收
  • 虚引用 , 最弱的一种引用关系, 一个对象是否有虚引用的存在, 完全不会对其生存时间构成影响, 也无法通过一个虚引用来获取一个实例对象, 唯一的目的就是为了能在被垃圾回收器回收的时候收到一个系统的通知

接下来我们来看看它们的api

SoftReference

import java.lang.ref.SoftReference;  
  
public class SoftReferenceExample {  
  
    // 使用 SoftReference 包装一个对象  
    private static class Cache<T> {  
        private final SoftReference<T> softRef;  
  
        public Cache(T object) {  
            this.softRef = new SoftReference<>(object);  
        }  
  
        public T get() {  
            return softRef.get();  
        }  
  
        public void set(T object) {  
            this.softRef = new SoftReference<>(object);  
        }  
    }  
  
    public static void main(String[] args) {  
        // 创建一个占用大量内存的对象,并包装在 SoftReference 中  
        byte[] largeArray = new byte[10 * 1024 * 1024]; // 10 MB  
        Cache<byte[]> cache = new Cache<>(largeArray);  
        largeArray = null; // 移除强引用  
  
        // 模拟一些操作  
        System.out.println("Initial Array: " + (cache.get() != null ? "Exists" : "Null"));  
  
        // 手动触发垃圾回收(通常不建议在生产环境中这样做)  
        System.gc();  
  
        // 此时 largeArray 应该仍然存在,因为内存还没有压力  
        System.out.println("After First GC: " + (cache.get() != null ? "Exists" : "Null"));  
  
        // 尝试分配大量内存以造成内存压力  
        byte[][] moreArrays = new byte[100][1024 * 1024]; // 100 MB  
  
        // 再次手动触发垃圾回收  
        System.gc();  
  
        // 此时 largeArray 可能会被回收,因为内存压力  
        System.out.println("After Memory Pressure and GC: " + (cache.get() != null ? "Exists" : "Null"));  
  
        // 释放 moreArrays 以减少内存压力  
        moreArrays = null;  
        System.gc();  
  
        // 如果此时 largeArray 被回收了,重新设置一个对象并测试  
        if (cache.get() == null) {  
            cache.set(new byte[10 * 1024 * 1024]); // 10 MB  
            System.out.println("Re-set Array: " + (cache.get() != null ? "Exists" : "Null"));  
        }  
    }  
}

 WeakReference

import java.lang.ref.WeakReference;  
  
public class WeakReferenceExample {  
  
    public static void main(String[] args) {  
        // 创建一个对象并通过 WeakReference 进行引用  
        String str = new String("Hello World");  
        WeakReference<String> weakRef = new WeakReference<>(str);  
  
        // 获取并打印被引用的对象  
        System.out.println("Weak reference value: " + weakRef.get());  
  
        // 清除强引用  
        str = null;  
  
        // 手动触发垃圾回收(通常不建议在生产环境中这样做)  
        System.gc();  
  
        // 尝试获取被引用的对象,此时应该为 null  
        System.out.println("Weak reference value after garbage collection: " + weakRef.get());  
    }  
}

 PhantomReference

        虚引用的get()方法始终返回null,因此无法通过虚引用来访问对象实例, 虚引用的工作机制主要依赖于ReferenceQueue。当一个对象被垃圾回收器确定为“不可达”(即所有强引用、软引用、弱引用都被清除),且它存在一个虚引用关联时,JVM会在回收该对象之前(或之后,具体取决于实现),将该虚引用插入到与之关联的ReferenceQueue中

import java.lang.ref.PhantomReference;  
import java.lang.ref.ReferenceQueue;  
  
public class PhantomReferenceExample {  
  
    public static void main(String[] args) {  
        // 创建一个对象  
        Object obj = new Object();  
  
        // 创建一个ReferenceQueue  
        ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();  
  
        // 创建一个PhantomReference  
        PhantomReference<Object> phantomRef = new PhantomReference<>(obj, referenceQueue);  
  
        // 清除强引用  
        obj = null;  
  
        // 手动触发垃圾回收(通常不建议在生产环境中这样做,这里仅用于测试)  
        System.gc();  
  
        // 等待垃圾回收器工作(这里使用简单的sleep来模拟等待,实际使用中应该避免这样做)  
        try {  
            Thread.sleep(1000);  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
  
        // 检查ReferenceQueue中是否有虚引用被加入  
        PhantomReference<?> polledRef = (PhantomReference<?>) referenceQueue.poll();  
        if (polledRef != null && polledRef == phantomRef) {  
            // 执行清理操作  
            System.out.println("Object has been garbage collected, performing cleanup...");  
            // 注意:这里不能直接通过phantomRef.get()访问对象,因为get()方法始终返回null  
        } else {  
            System.out.println("Object has not been garbage collected yet.");  
        }  
    }  
}

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

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

相关文章

OAuth2.0 设备授权流程

OAuth2.0设备授权流程&#xff08;Device Authorization Grant&#xff09;是一种为缺乏输入能力的设备&#xff08;例如智能电视、游戏机、物联网设备等&#xff09;设计的授权模式。这些设备通常不具备复杂的键盘或指定输入方式&#xff0c;无法直接进行OAuth2.0标准的交互授…

8c语言基础文件

关于文件你必须了解的一些基本概念 什么是文件&#xff1f; 文件是计算机文件&#xff0c;属于文件的一种&#xff0c;与普通文件的载体不同&#xff0c;计算机文件是以计算机硬盘为载体存储在计算机上的信息集合。 在程序设计中&#xff0c;我们一般关注的文件有两类&#x…

【C++】空指针和野指针

文章目录 1.空指针2.野指针总结 1.空指针 概念&#xff1a;指针变量指向内存中编号为0的空间。 用途&#xff1a;初始化指针变量。 注意&#xff1a;空指针指向的内存是不可以访问的。 示例&#xff1a; int main(){//指针变量p指向内存地址编号为0的空间int *PNULL&#…

从零开始学cv-15:图像分割

文章目录 前言一、全局阈值分割&#xff1a;二、自适应阈值分割&#xff1a;三、分水岭算法&#xff1a; 前言 在当代计算机视觉领域&#xff0c;图像分割技术扮演着至关重要的角色&#xff0c;它为图像理解、目标识别和场景解析等高级视觉任务提供了基础。OpenCV&#xff0c;…

Redis:hash类型

Redis&#xff1a;hash类型 hash命令设置与读取HSETHGETHMGET 哈希操作HEXISTSHDELHKEYSHVALSHGETALLHLENHSETNXHINCRBYHINCRBYFLOAT 内部编码ziplisthashtable 目前主流的编程语言中&#xff0c;几乎都提供了哈希表相关的容器&#xff0c;Redis自然也会支持对应的内容&#xf…

李宏毅深度学习-循环神经网络RNN

Recurrent Neural Network 这个问题可以使用一个前馈神经网络&#xff08;feedforward neural network&#xff09;来解&#xff0c;如图5.2 所示&#xff0c; 输入是一个单词&#xff0c;把“上海”变成一个向量&#xff0c;“丢”到这个神经网络里面。输入是一个单词&#x…

平衡二叉搜索树---java---黑马

平衡二叉搜索树 AVL树的实现 二叉搜索树在插入和删除时&#xff0c;节点可能发生失衡&#xff1b;如果在插入和删除时通过旋转&#xff0c;始终让二叉搜索树保持平衡&#xff0c;称之为平衡二叉搜索树&#xff1b;AVL树是自平衡二叉搜索树的实现之一 LL - 失衡节点(图中5红…

项目-坦克大战学习笔记-地图完善

之前我们详细讲解了怎么在地图上绘制墙&#xff0c;这次我们来完善整个地图&#xff0c; 地图的静态物体构成分为可破坏的墙体&#xff0c;不可破坏的铁块&#xff0c;以及最终boos 那我们为了方便存储将三个对象分开放为3个列表 private static List<gudin> walllist…

vscode有问题

开始给我报错&#xff0c;说命名不规范 然后我就改&#xff0c;改了好几遍之后还是报错。问了ai&#xff0c;也用它的方法改了&#xff0c;还是报错。。。 然后关掉vscode&#xff0c;重启&#xff0c;&#xff0c;&#xff0c;&#xff0c;&#xff0c;&#xff0c;运行成功

【算法系列-链表】删除链表的倒数第N个结点

【算法系列-链表】删除链表的倒数第N个结点 文章目录 【算法系列-链表】删除链表的倒数第N个结点1. 算法分析&#x1f6f8;2. 模拟解决问题2.1 思路分析&#x1f3af;2.2 代码示例&#x1f330; 3. 双指针(快慢指针)解决问题3.1 思路分析&#x1f3af;3.2 代码示例&#x1f330…

Web-Machine-N7解题过程

1.主机探测 arp-scan -lnmap -sn 192.168.1.0/24sudo netdiscover -r 192.168.1.0/24masscan -p0-65535 192.168.1.0/24 2.端口扫描 nmap -A -sC -sT -sV 192.168.1.188 --min-rate 10000 &#xff08;简略扫描&#xff09;nmap -sS 192.168.1.188 -A&#xff1a; 启用操作系…

vue的图片显示

通过参数 调用方法 进行显示图片 方法一: 方法二:

使用TM1618控制LED了解P-MOS和N-MOS的开漏输出的不同

数据手册上的截取内容 推荐的共阴/阳极电路 可以发现GRID总接LED的负极&#xff0c;SEG引脚接的是LED 正极 分析输出的MOS管类型可以很好的知道原因 图片来源 通过都是开漏输出可以看出&#xff0c;引脚引出的内部电路是不同的。P-mos引出的是漏极&#xff0c;导通时&#…

平面电磁波的能量传输速度——就记平均坡印廷矢量/平均能量密度(物理意义,坡印廷是单位时间该点流过的能量,能量密度表示该店有多少能量。如果能量密度不变,经过流动速度是2/s,则1s流过的能量就是2*密度

能量传输速度 平均坡印廷矢量的模&#xff08;功率流密度&#xff09;/ 电磁波平均能量密度&#xff08;电场和磁场的都算进去&#xff09; 能量传输速度等于相速度 但是文心给出的能量流动速度的定义是

2. 术语解释(类、成员变量、行为、属性、this)以及注销账号和空指针异常

文章目录 1. 类2. 成员变量3. 行为4. 属性5. zhangDog.name 以及 zhangDog.sleep()解析6. this① 提出问题② 解决方案③ 进一步完善&#xff1a;引入this 7. 注销账号8. 空指针异常9. 内容出处 1. 类 我们的目的是不是要给狗写一个程序&#xff0c;而且要让所有狗都能用&#…

20241004给荣品RD-RK3588-AHD开发板刷Rockchip原厂的Android12【HDMI0显示】

20241004给荣品RD-RK3588-AHD开发板刷Rockchip原厂的Android12【HDMI0显示】 2024/10/4 19:40 1、配置RK3588S的默认DTS为&#xff1a;rk3588s-evb4-lp4x-v10.dts D:\Android\rk3588s4_3588a12\device\rockchip\rk3588\rk3588s_s\BoardConfig.mk Z:\rk3588s4_3588a12\device\ro…

【论文笔记】Efficient LoFTR: Semi-Dense Local Feature Matching with Sparse-Like Speed

【引用格式】&#xff1a;Wang Y, He X, Peng S, et al. Efficient LoFTR: Semi-dense local feature matching with sparse-like speed[C]//Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition. 2024: 21666-21675. 【网址】&#xff1a;ht…

PostgreSQL Docker Error – 5432: 地址已被占用

PostgreSQL Docker Error – 5432: 地址已被占用 今天在学习【Spring Boot React】价值79.9美元&#xff0c;全栈开发&#xff0c;搭建个人网站、做毕业设计、试试这套课程第17~21节视频的时候&#xff0c;发现运行docker run --name demo-postgres -e POSTGRES_PASSWORDpass…

数据集-目标检测系列- 货船 检测数据集 freighter>> DataBall

数据集-目标检测系列- 货船 检测数据集 freighter>> DataBall 数据集-目标检测系列- 货船 检测数据集 freighter>> DataBall 数据量&#xff1a;3k 想要进一步了解&#xff0c;请联系。 DataBall 助力快速掌握数据集的信息和使用方式&#xff0c;会员享有 百种…

高效参数微调

一、增加额外参数的方法 这些方法通过向模型中添加额外的可训练参数&#xff0c;而不修改原有的预训练模型参数。 1. Prefix Tuning&#xff08;前缀微调&#xff09; 原理&#xff1a;在每一层的输入添加一组可训练的“前缀”向量&#xff0c;这些前缀向量会影响模型的输出…