系列四、强引用、软引用、弱引用、虚引用分别是什么?

一、整体架构

二、强引用(默认支持模式)

2.1、概述

        当内存不足时,JVM开始垃圾回收,对于强引用的对象,就算是出现了OOM也不会对该对象进行回收,死都不收。

        强引用是我们最常见的普通对象引用,只要还有强引用指向另一个对象,就表明该对象还"活着",垃圾收集器不会回收这种对象。在Java中最常见的就是强引用,把一个对象赋给一个

一个引用变量,这个引用变量就是一个强引用。当一个对象被强引用变量引用时,它处于可达状态,它是不可能被垃圾回收器回收的,即使该对象永远都不会被JVM回收。因此强引用是造成Java内存泄露的主要原因之一。

        对于一个普通的对象,如果没有其他的引用关系,只要超过了引用的作用域或者显示地将强引用赋值为null,一般认为就是可被垃圾收集器收集的了。(具体回收时机还是要看垃圾收集策略)。

2.2、案例代码

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/19 18:13
 * @Description: 强引用案例演示
 */
public class StrongReferenceMainApp {

    public static void main(String[] args) {
        // 这样定义的默认就是强引用
        Object o1 = new Object();

        // o2引用赋值
        Object o2 = o1;

        // o1置空
        o1 = null;

        System.gc();
        System.out.println(o2);
        System.out.println(o1 == null);
        System.out.println(o2 == null);
    }

}

三、软引用

3.1、概述

        软引用是一种相对强引用弱化了一些的引用,需要用java.lang.ref.SoftReference类来实现,可以让对象豁免一些垃圾收集。

        对于只有弱引用的对象来说:

                当系统内存充足时,不会被回收;

                当系统内存不足时,会被回收;

        软引用通常用在对内存敏感的程序中,比如高速缓存就有用到软引用,内存够用的时候就保留,不够用就回收!

3.2、案例代码

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/19 18:13
 * @Description: 软引用案例演示
 */
public class SoftReferenceMainApp {

    public static void main(String[] args) {
        Object o1 = new Object();
        SoftReference<Object> softReference = new SoftReference<>(o1);
        System.out.println(o1);
        System.out.println(softReference.get());

        o1 = null;
        System.gc();

        System.out.println(o1);
        System.out.println(softReference.get());

    }

}

四、弱引用

4.1、概述

        弱引用需要使用java.lang.ref.WeakReference类来实现,它比软引用的生存期更短。

        

        对于只有弱引用的对象来说,只要垃圾回收机制一运行,不管JVM的内存是否足够,都会回收该对象占用的内存;

4.2、案例代码

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/19 18:13
 * @Description: 弱引用案例演示
 */
public class WeakReferenceMainApp {

    public static void main(String[] args) {
        Object o1 = new Object();
        WeakReference<Object> weakReference = new WeakReference<>(o1);
        System.out.println(o1);
        System.out.println(weakReference.get());

        o1 = null;
        System.gc();

        System.out.println(o1);
        System.out.println(weakReference.get());

    }

}

4.3、软引用和弱引用的适用场景

假设有一个应用需要读取大量的本地图片:

        如果每次读取图片都从硬盘读取,则会严重影响性能;

        如果一次性全部加载大内存中,又有可能造成内存溢出;

        此时,可以使用软引用来解决这个问题,思路如下:

        用一个HashMap来保存图片的路径和相应图片对象关联的弱引用之间的映射关系,当内存不足时,JVM自动回收这些缓存图片对象所占用的空间,从而有效的避免OOM的问题。

        Map<String,SoftReference<Bitmap>> imageCache = new HashMap<String,SoftReference<Bitmap>>();

4.4、你知道弱引用的话,能谈谈WeakHashMap吗

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/19 18:44
 * @Description: 你知道弱引用,能谈谈WeakHashMap吗?
 */
public class WeakHashMapMainApp {

    public static void main(String[] args) {
        WeakHashMap<Integer, String> map = new WeakHashMap<>();
        Integer key = new Integer(2);
        String value = "weakHashMap";

        map.put(key, value);
        System.out.println(map);

        key = null;
        System.out.println(map);

        System.gc();
        System.out.println(map + "\t" + map.size());

    }

}

五、虚引用 

5.1、概述

        虚引用需要java.lang.ref.PhantomReference类来实现。

        顾名思义,虚引用就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾收集器回收,它不能单独使用也不能通过它来访问对象,虚引用必须和引用队列(ReferenceQueue)联合使用。

        虚引用的主要作用是用来跟踪对象被垃圾回收的状态。仅仅是提供了一种确保对象被finalize以后,做某些事情的机制。

        PhantomReference的get()总是返回null,因此无法访问对应的引用对象。其意义在于说明一个对象已经进入finalization阶段,可以被gc回收,用来实现比finalization机制更灵活的回收操作。

        换句话说,设置虚引用关联的唯一目的就是在这个对象被收集器回收的时候,收到一个系统通知或者后续执行进一步的处理。

        Java技术允许使用finalize()方法在垃圾收集器将对象从内存中清除之前做必要的清理工作。

5.2、引用队列

5.3、案例代码

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/19 19:10
 * @Description: 虚引用案例代码
 */
public class PhantomReferenceMainApp {

    public static void main(String[] args) {
        Object o1 = new Object();
        ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
        PhantomReference<Object> phantomReference = new PhantomReference<>(o1,referenceQueue);

        System.out.println(o1);
        System.out.println(phantomReference.get());
        System.out.println(referenceQueue.poll());
    }

}

六、GCRoot和四大引用小总结

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Gin框架源码解析

概要 目录 Gin路由详解 Gin框架路由之Radix Tree 一、路由树节点 二、请求方法树 三、路由注册以及匹配 中间件含义 Gin框架中的中间件 主要讲述Gin框架路由和中间件的详细解释。本文章将从Radix树&#xff08;基数树或者压缩前缀树&#xff09;、请求处理、路由方法树…

hypermesh学习总结(一)

1、hypermesh导入导出 2、hypermesh如何使用拓扑命令,连接多个几何体为一个? 3、hypermesh模式选择 分别有显示动力学模式explicit,标准模式Standard3D(静力学及模态等)

Linux之进程概念(一)

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、冯诺依曼体系结构二、操作系统(Operator System)1、概念2、设计OS的目的3、定位4、如何理…

2024年csdn最新最全的Postman接口测试: postman实现参数化

什么时候会用到参数化 比如&#xff1a;一个模块要用多组不同数据进行测试 验证业务的正确性 Login模块&#xff1a;正确的用户名&#xff0c;密码 成功&#xff1b;错误的用户名&#xff0c;正确的密码 失败 postman实现参数化 在实际的接口测试中&#xff0c;部分参数…

弗洛伊德算法(C++)

目录 介绍&#xff1a; 代码&#xff1a; 结果&#xff1a; 介绍&#xff1a; 弗洛伊德算法&#xff08;Floyd algorithm&#xff09;也称为Floyd-Warshall算法&#xff0c;是一种用于求解所有节点对之间的最短路径的动态规划算法。它使用了一个二维数组来存储所有节点…

深入解析具名导入es6规范中的具名导入是在做解构吗

先说答案&#xff0c;不是 尽管es6的具名导入和语法非常相似 es6赋值解构 const obj {a: 1,f() {this.a}}const { a, f } objes6具名导入 //导出文件代码export let a 1export function f() {a}export default {a,f}//导入文件代码import { a, f } from ./tsVolution可以看出…

Unity2021及以上 启动或者禁用自动刷新

Unity 2021以以上启动自动刷新 Edit---> Preferences--> Asset Pipline --> Auto Refresh 禁用的结果 如果不启动自动刷新在Project面板选择Refresh是不会刷新已经修改后的脚本的。

10_6 input输入子系统,流程解析

简单分层 应用层 内核层 --------------------------- input handler 数据处理层 driver/input/evdev.c1.和用户空间交互,实现fops2.不知道数据怎么得到的,但是可以把数据上传给用户--------------------------- input core层1.维护上面和下面的两个链表2.为上下两层提供接口--…

智慧路灯控制系统设计方案思路及设计原则

智慧路灯系统依托于智慧路灯综合管理平台&#xff0c;实现点&#xff08;智慧路灯&#xff09;、线&#xff08;道路&#xff09;、面&#xff08;城市&#xff09;的三级监控&#xff0c;实现灯控、屏控、视频监控、数据采集、联动的统一。 1&#xff09;一个城市的智慧路灯系…

Shell判断:流程控制—if(三)

一、调试脚本 1、调试脚本的其他方法&#xff1a; [rootlocalhost ~] # sh -n useradd.sh 仅调试脚本中的语法错误。 [rootlocalhost ~]# sh -vx useradd.sh 以调试的方式执行&#xff0c;查询整个执行过程。 2、示例&#xff1a; [rootlocalhost ~]# sh -n useradd.sh #调…

【数据结构&C++】二叉平衡搜索树-AVL树(25)

前言 大家好吖&#xff0c;欢迎来到 YY 滴C系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; 目录 一.AVL树的概念二.AVL树节点的定义(代码…

OpenHarmony源码下载

OpenHarmony源码下载 现在的 OpenHarmony 4.0 源码已经有了&#xff0c;在 https://gitee.com/openharmony 地址中&#xff0c;描述了源码获取的方式&#xff0c;但那是基于 ubuntu 或者说是 Linux 的下载方式。在 windows 平台下的下载方式没有做出介绍。 我自己尝试了 wind…

linux文件IO

文件IO截断 截断对文件的偏移量没有影响。

【Go入门】 Go如何使得Web工作

【Go入门】 Go如何使得Web工作 前面小节介绍了如何通过Go搭建一个Web服务&#xff0c;我们可以看到简单应用一个net/http包就方便的搭建起来了。那么Go在底层到底是怎么做的呢&#xff1f;万变不离其宗&#xff0c;Go的Web服务工作也离不开我们第一小节介绍的Web工作方式。 w…

简单聊一聊幂等和防重

大家好&#xff0c;我是G探险者。 每年的双十一&#xff0c;618&#xff0c;电商系统都会面临这超高的流量&#xff0c;如果一个订单被反复提交&#xff0c;那电商系统如何保证这个订单之后执行一次减库存&#xff0c;扣款的操作&#xff1f; 这里就引入两个概念&#xff0c;…

python-opencv 培训课程笔记(1)

python-opencv 培训课程笔记&#xff08;1&#xff09; 博主参加了一次opencv库的培训课程&#xff0c;把课程所学整理成笔记&#xff0c;供大家学习&#xff0c;第一次课程包括如下内容&#xff1a; 1.读取图像 2.保存图像 3.使用opencv库显示图像 4.读取图像为灰度图像 …

常见树种(贵州省):003柏类

摘要&#xff1a;本专栏树种介绍图片来源于PPBC中国植物图像库&#xff08;下附网址&#xff09;&#xff0c;本文整理仅做交流学习使用&#xff0c;同时便于查找&#xff0c;如有侵权请联系删除。 图片网址&#xff1a;PPBC中国植物图像库——最大的植物分类图片库 一、柏木 …

【Go入门】Web工作方式

【Go入门】 Web工作方式 我们平时浏览网页的时候,会打开浏览器&#xff0c;输入网址后按下回车键&#xff0c;然后就会显示出你想要浏览的内容。在这个看似简单的用户行为背后&#xff0c;到底隐藏了些什么呢&#xff1f; 对于普通的上网过程&#xff0c;系统其实是这样做的&…

OpenAI Assistants-API简明教程

OpenAI在11月6号的开发者大会上&#xff0c;除了公布了gpt4-v、gpt-4-turbo等新模型外&#xff0c;还有一个assistants-api&#xff0c;基于assistants-api开发者可以构建自己的AI助手&#xff0c;目前assistants-api有三类的工具可以用。首先就是之前大火的代码解释器(Code In…

Ubuntu系统安装Python3.6.8-Python源代码编译安装-Python环境安装

一、背景 本文将着重介绍如何在Python环境下&#xff0c;安装Python3.6.8&#xff0c;以满足在Ubuntu系统中使用Python的需求。 二、详细步骤 安装Python的方法有很多&#xff0c;本文中我们采用源代码的方式安装Python&#xff0c;首先我们需要下载Python源代码&#xff1a;源…