Java 中的四种引用方式

2023-09-14 15:41:30

Java 中的四种引用方式

1、强引用(Strong Reference)
  • 强引用是最普遍的引用
  • 当一个对象是强引用,垃圾回收器绝不会回收他
  • 当内存不足时,JVM 宁愿抛出 OutOfMemoryError 错误,也不会回收具有强引用的对象,来解决内存不足问题
Object strongReference = new Object();
  • 如果强引用对象不使用时,需要 弱化从而使 GC 能够回收
(1)弱化方式1
  • 显示的设置 strongReference 对象为null,则 gc 认为该对象不存在引用,这时就可以回收这个对象

  • 如果 strongReference 是 全局变量,就需要在不用这个对象时赋值为null,因为强引用不会被垃圾回收。

strongReference = null;

应用场景:在ArrayList集合类中定义elementData数组,在调用clear()方法清空集合元素时,将每个数组元素被赋值为null。目的是为了将内存数组中存放的引用类型进行内存释放,可以及时释放内存。不选择将elementData=null,是为了避免在后续调用add()等方法添加新元素时,需要进行内存的重新分配

//ArrayList 源码
public void clear() {
    modCount++;

    // clear to let GC do its work
    for (int i = 0; i < size; i++)
        elementData[i] = null;

    size = 0;
}
(2)弱化方式2

让对象超出作用域范围,即缩小强引用的作用范围

public void test() {
    Object strongReference = new Object();
    // 省略其他操作
}

应用场景:在一个方法的内部有一个强引用,这个引用保存在VM Stack中(GC Root*),而真正的引用对象(Object)保存在中。当这个方法运行完成后,就会退出方法栈,则这个对象会被回收。

2、软引用(Soft Reference)
  • 如果一个对象只具有软引用,则 内存空间充足 时,垃圾回收器就不会回收它
  • 如果 内存空间不足时 ,就会回收这些对象,从而释放内存
  • 软引用可以用来实现内存敏感的高速缓存

使用 SoftReference 创建软引用

// 定义和访问软引用
// 强引用
String strongReference = new String("abc");

// 软引用
String str = new String("abc");
SoftReference<String> softReference = new SoftReference<String>(str);

// 访问软引用
softReference.get();
  • 软引用对象是在jvm内存不够的时候才会被回收,我们调用System.gc()方法只是起通知作用,最终何时回收,由JVM决定。
  • 所以,当内存不足时,JVM首先将软引用中的对象引用置为null,然后通知垃圾回收器进行回收:
//回收软引用
// 软引用
String str = new String("abc");
SoftReference<String> softReference = new SoftReference<>(str);

str = null;

// Notify GC
System.gc();

try {
    byte[] buff1 = new byte[900000000]; // 内存充沛
    // byte[] buff2 = new byte[900000000]; // 内存不足
} catch (Error e) {
    e.printStackTrace();
}

System.out.println(softReference.get()); // abc 或 null

**应用场景:**短视频APP中的视频缓存,后退时,显示的短视频内容是重新进行请求还是从缓存中取出呢?

  1. 如果一个短视频在播放结束时,就进行内容的回收,则后退查看前面播放的短视频时,需要重新请求。
  2. 如果将播放过的短视频存储到内存中,会造成内存的开销,甚至会造成内存溢出。

此时,可以使用软引用解决这个实际问题:

//软引用案例
// 获取视频播放器对象
Player videoAlayer = new Player();

// 加载短视频
Video video = audioAlayer.getVideo();

// 将播放完毕的短视频设置为软引用
SoftReference softReference = new SoftReference(video);

// 回退或者再次播放时
if(softReference.get() != null) {
    // 内存充足,还没有被回收器回收,直接获取缓存
    video = softReference.get();
} else {
    // 内存不足,软引用的对象已经回收
    video = audioAlayer.getVideo();
    // 重新构建软引用
    softReference = new SoftReference(video);
}
3、弱引用(Weak Reference)
  • 只具有 弱引用 的对象拥有 更短暂生命周期
  • 在垃圾回收器扫描的时候,不管内存是否足够,都会回收它的内存

创建弱引用,使用 WeakReference

String str = new String("abc");
WeakReference<String> weakReference = new WeakReference<>(str);
str = null;

System.gc();
		
// 一旦发生GC,弱引用一定会被回收
System.out.println(weakReference.get());
4、虚引用(Phantom Reference)
  • 虚引用是最弱的一种引用关系
  • 如果一个对象仅持有虚引用,完全不会对其生存时间构成影响,它就和没有任何引用一样,随时可能会被回收
  • 主要用来跟踪对象被垃圾回收的活动,可以在垃圾收集时收到一个系统通知
public class PhantomReference<T> extends Reference<T> {
    public T get() {
        return null;
    }
}
更多推荐

二叉树的遍历

Ⅰ、二叉树基本介绍1.1、二叉树的定义二叉树(binarytree)是指树中节点的度不大于2的有序树,它是一种最简单且最重要的树。二叉树的递归定义为:二叉树是一棵空树,或者是一棵由一个根节点和两棵互不相交的,分别称作根的左子树和右子树组成的非空树;左子树和右子树又同样都是二叉树。1.2、特殊的二叉树1、满二叉树:如果一

【算法训练-二叉树 三】【最大深度与直径】求二叉树的最大深度、求二叉树的直径

废话不多说,喊一句号子鼓励自己:程序员永不失业,程序员走向架构!本篇Blog的主题是【求二叉树的直径】,使用【二叉树】这个基本的数据结构来实现,这个高频题的站点是:CodeTop,筛选条件为:目标公司+最近一年+出现频率排序,由高到低的去牛客TOP101去找,只有两个地方都出现过才做这道题(CodeTop本身汇聚了Le

JavaWeb 学习笔记 5:JSP

JavaWeb学习笔记5:JSP简单的说,JSP就是Java+Html,JSP的出现是为了让JavaWeb应用生成动态页面更容易。1.快速开始1.1.依赖添加JSP依赖:<dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifa

元素全排列问题的新思路(DFS,递归,计数器)

目录前言1,普通DFS实现1~n的元素全排列2,计数器+DFS实现重复元素全排列总结前言我们之前看到的全排列问题的解法都是通过交换法达到的,去重的效果也是通过判断当前元素前是否有相同元素来实现,今天我们带来一个全新的思路,使我们直接进行深度优先搜索+一个计数器就可以实现,不用交换。1,普通DFS实现1~n的元素全排列我

数据结构 | 数据结构的“基本概念”和“术语”

数据结构的“基本概念”和“术语”:1.数据(Data)2.数据元素(DataElement)3.数据项(DateItem)4.数据、数据元素、数据项三者之间的关系5.数据对象(DataObject)6.数据结构(DataStructure)6.1数据结构(DataStructure)的种类/两个层次:逻辑结构逻辑结构的

数据结构入门 — 二叉树的概念、性质及结构

本文属于数据结构专栏文章,适合数据结构入门者学习,涵盖数据结构基础的知识和内容体系,文章在介绍数据结构时会配合上动图演示,方便初学者在学习数据结构时理解和学习,了解数据结构系列专栏点击下方链接。博客主页:DuckBro博客主页系列专栏:数据结构专栏关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢

Mysql高级——索引优化和查询优化(1)

索引优化1.数据准备学员表插50万条,班级表插1万条。建表CREATETABLE`class`(`id`INT(11)NOTNULLAUTO_INCREMENT,`className`VARCHAR(30)DEFAULTNULL,`address`VARCHAR(40)DEFAULTNULL,`monitor`INTN

数据科学中的数据库简介

推荐:使用NSDT场景编辑器快速搭建3D应用场景用于高效视频、AI和图形的通用加速器数据科学中的数据库简介数据科学涉及从大量数据中提取价值和见解,以推动业务决策。它还涉及使用历史数据构建预测模型。数据库有助于对如此大量的数据进行有效的存储、管理、检索和分析。因此,作为一名数据科学家,您应该了解数据库的基础知识。因为它们

安卓页面绘制流程(3)Window注册

前言:本文属于安卓页面绘制流程的第3篇,主要介绍应用是如何把APP侧的Window向system进行注册的。主要分为2大块:第一块,APP侧在resume周期时向系统侧申请绑定。第二块,系统侧收到请求后处理绑定的流程。一.APP侧Window注册在上一篇文章中,我们已经讲过,在Activity的create周期内,其所

什么是Vue的自定义指令(custom directives)?如何自定义指令?

聚沙成塔·每天进步一点点⭐专栏简介⭐Vue.js的自定义指令⭐示例⭐写在最后⭐专栏简介前端入门之旅:探索Web开发的奇妙世界欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发者,这里都将为你提供一个系统而又亲切的

Learn Prompt-Prompt 高级技巧:MetaGPT

MetaGPT是一项引起广泛关注的研究成果,它引入了一个将人工工作流程与多智能体协作无缝集成的框架。通过将标准化操作(SOP)程序编码为提示,MetaGPT确保解决问题时采用结构化方法,从而减少出错的可能性。🎉开始阅读前,如果你对其他文章感兴趣,可以到欢迎页关注我们!「卡尔的AI沃茨」开源中文社区实时获得后续的更新和

热文推荐