java弱引用怎么手动释放,十分钟理解Java中的弱引用,十分钟java引用

十分钟理解Java中的弱引用,十分钟java引用

本篇文章尝试从What、Why、How这三个角度来探索Java中的弱引用,帮助大家理解Java中弱引用的定义、基本使用场景和使用方法。由于个人水平有限,叙述中难免存在不准确或是不清晰的地方,希望大家可以指出,谢谢大家:)

1. What——什么是弱引用?

Java中的弱引用具体指的是java.lang.ref.WeakReference类,我们首先来看一下官方文档对它做的说明:

弱引用对象的存在不会阻止它所指向的对象被垃圾回收器回收。弱引用最常见的用途是实现规范映射(canonicalizing mappings,比如哈希表)。

假设垃圾收集器在某个时间点决定一个对象是弱可达的(weakly reachable)(也就是说当前指向它的全都是弱引用),这时垃圾收集器会清除所有指向该对象的弱引用,然后把这个弱可达对象标记为可终结(finalizable)的,这样它随后就会被回收。与此同时或稍后,垃圾收集器会把那些刚清除的弱引用放入创建弱引用对象时所指定的引用队列(Reference Queue)中。

实际上,Java中存在四种引用,它们由强到弱依次是:强引用、软引用、弱引用、虚引用。下面我们简单介绍下除弱引用外的其他三种引用:

强引用(Strong Reference):通常我们通过new来创建一个新对象时返回的引用就是一个强引用,若一个对象通过一系列强引用可到达,它就是强可达的(strongly reachable),那么它就不被回收

软引用(Soft Reference):软引用和弱引用的区别在于,若一个对象是弱引用可达,无论当前内存是否充足它都会被回收,而软引用可达的对象在内存不充足时才会被回收,因此软引用要比弱引用“强”一些

虚引用(Phantom Reference):虚引用是Java中最弱的引用,那么它弱到什么程度呢?它是如此脆弱以至于我们通过虚引用甚至无法获取到被引用的对象,虚引用存在的唯一作用就是当它指向的对象被回收后,虚引用本身会被加入到引用队列中,用作记录它指向的对象已被回收。

Why——为什么使用弱引用?

考虑下面的场景:现在有一个Product类代表一种产品,这个类被设计为不可扩展的,而此时我们想要为每个产品增加一个编号。一种解决方案是使用HashMap。于是问题来了,如果我们已经不再需要一个Product对象存在于内存中(比如已经卖出了这件产品),假设指向它的引用为productA,我们这时会给productA赋值为null,然而这时productA过去指向的Product对象并不会被回收,因为它显然还被HashMap引用着。所以这种情况下,我们想要真正的回收一个Product对象,仅仅把它的强引用赋值为null是不够的,还要把相应的条目从HashMap中移除。显然“从HashMap中移除不再需要的条目”这个工作我们不想自己完成,我们希望告诉垃圾收集器:在只有HashMap中的key在引用着Product对象的情况下,就可以回收相应Product对象了。显然,根据前面弱引用的定义,使用弱引用能帮助我们达成这个目的。我们只需要用一个指向Product对象的弱引用对象来作为HashMap中的key就可以了。

How——如何使用弱引用?

拿上面介绍的场景举例,我们使用一个指向Product对象的弱引用对象来作为HashMap的key,只需这样定义这个弱引用对象:

Product productA = new Product(...);

WeakReference weakProductA = new WeakReference<>(productA);

现在,若引用对象weakProductA就指向了Product对象productA。那么我们怎么通过weakProduct获取它所指向的Product对象productA呢?很简单,只需要下面这句代码:

Product product = weakProductA.get();

实际上,对于这种情况,Java类库为我们提供了WeakHashMap类,使用和这个类,它的键自然就是弱引用对象,无需我们再手动包装原始对象。这样一来,当productA变为null时(表明它所引用的Product已经无需存在于内存中),这时指向这个Product对象的就是由弱引用对象weakProductA了,那么显然这时候相应的Product对象时弱可达的,所以指向它的弱引用会被清除,这个Product对象随即会被回收,指向它的弱引用对象会进入引用队列中。

引用队列

下面我们来简单地介绍下引用队列的概念。实际上,WeakReference类有两个构造函数:

//创建一个指向给定对象的弱引用

WeakReference(T referent)

//创建一个指向给定对象并且登记到给定引用队列的弱引用

WeakReference(T referent, ReferenceQueue super T> q)

我们可以看到第二个构造方法中提供了一个ReferenceQueue类型的参数,通过提供这个参数,我们便把创建的弱引用对象注册到了一个引用队列上,这样当它被垃圾回收器清除时,就会把它送入这个引用队列中,我们便可以对这些被清除的弱引用对象进行统一管理。

参考资料

WeakReference (Java Platform SE 7 ) – Oracle Help Center

理解Java中的弱引用

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

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

相关文章

软件:推荐六款实用的录频软件

❤️作者主页&#xff1a;IT技术分享社区 ❤️作者简介&#xff1a;大家好,我是IT技术分享社区的博主&#xff0c;从事C#、Java开发九年&#xff0c;对数据库、C#、Java、前端、运维、电脑技巧等经验丰富。 ❤️个人荣誉&#xff1a; 数据库领域优质创作者&#x1f3c6;&#x…

安装 openSUSE Leap 42.1 之后要做的 8 件事

导读openSUSE Leap 确实是个巨大的飞跃&#xff0c;它允许用户运行一个和 SUSE Linux 企业版拥有同样基因的发行版。和其它系统一样&#xff0c;为了实现最佳的使用效果&#xff0c;在使用它之前需要做些优化设置。下面是一些我在我的电脑上安装 openSUSE Leap 之后做的一些事情…

Java8 Stream Collectors groupingBy使用

分组List并显示其总数。 Test public void test8() {//3 apple, 2 banana, others 1List<String> items Arrays.asList("apple", "apple", "banana","apple", "orange", "banana", "papaya");Map…

操作系统:分享10个经常用的cmd命令

电脑高手操作电脑时&#xff0c;通常都是在“运行”中直接输入“命令”来直接调出相应的操作。如果大家也想要像电脑高手一样&#xff0c;但是却又不知道“运行”命令有哪些&#xff1f;在这里&#xff0c;小编就为大家分享10个“运行”命令&#xff0c;让大家体验到成为电脑高…

matlab交叉耦合,交叉耦合矩阵综合问题

编程计算N阶耦合矩阵&#xff0c;基本都能算对&#xff0c;但是对于某些特殊参数会出现R1!RN&#xff0c;大家又出现类似的情况么&#xff1f;希望高手帮忙计算以下参数&#xff0c;看看是否能算出来。参数为ftz[-1.2i -1.4i 1.4i 1.2i -1.05i 1.05i];传输零点RL20;%带内回波N …

idea创建Package时出现包名累加,而不是树形结构解决方法

idea打开工程的时候包名叠在一起了 点击箭头处按钮,把第一第二行勾去掉 如下 最终效果

电脑键盘中英文按键有哪些?有什么作用?

对于电脑键盘&#xff0c;相信大家并不陌生&#xff0c;而在电脑键盘上面有着很多按键&#xff0c;除了数字按键和字母按键之外&#xff0c;还有很多看不懂的英文按键。那么这些英文按键是什么意思呢&#xff1f;如果并不了解&#xff0c;那么小编就为大家介绍所有英文按键的意…

在github中使用pages上传自己的网页

转载自&#xff1a;http://www.cnblogs.com/lijiayi/p/githubpages.html 学了前端小半年&#xff0c;如今写了个自己的网页想要去应聘&#xff0c;却发现部署很麻烦&#xff0c;部署到阿里云之类&#xff0c;买域名啊啥的还要收费&#xff0c;说贵也不贵&#xff0c;但我就是傲…

使用lamba中stream 进行分组统计

对一个list中的元素进行分组&#xff0c;并统计各个元素出现的次数。放入map<String,Long>。 代码如下: Test public void test8() {List<String> items Arrays.asList("1", "2", "3","4", "1", "3"…

php 表单select,表单控件select标签是如何使用的

表单控件select标签是用来创建下拉列表的&#xff0c;通过标签来定义可用选项以及其他属性来设置表单控件的选择个数等。今天将介绍的是HTML中的表单控件select的用法&#xff0c;具有一定的参考价值&#xff0c;希望对大家有所帮助。【推荐课程&#xff1a;HTML教程】select标…

电脑经常死机是什么原因?如何解决?

目录 一、电脑经常死机是什么原因&#xff1f; 二、电脑经常死机如何解决&#xff1f; ​​​​​​​ 一、电脑经常死机是什么原因&#xff1f; 1、电脑频繁死机&#xff0c;在进行CMOS设置时也会出现死机现象&#xff0c;一般由硬件问题引起的&#xff0c;散热不良…

重量级框架

1.概述 重量级框架则强调高可伸缩性&#xff0c;适合与开发大型企业应用。轻量级框架侧重于减小开发的复杂度&#xff0c;相应的它的处理能力便有所减弱&#xff08;如事务功能弱、不具备分布式处理能力&#xff09;&#xff0c;比较适用于开发中小型企业应用。轻量级框架和重量…

Win10磁盘占用达到100%,优化一下就解决了

❤️作者主页&#xff1a;IT技术分享社区 ❤️作者简介&#xff1a;大家好,我是IT技术分享社区的博主&#xff0c;从事C#、Java开发九年&#xff0c;对数据库、C#、Java、前端、运维、电脑技巧等经验丰富。 ❤️个人荣誉&#xff1a; 数据库领域优质创作者&#x1f3c6;&#x…

2、IDEA以新窗口的形式打开多个项目

IDEA以新窗口的形式打开多个项目 修改1处如图所示

160523、Oracle建立表空间和用户

建立表空间和用户的步骤&#xff1a; 用户 建立&#xff1a;create user 用户名 identified by "密码"; 授权&#xff1a;grant create session to 用户名; grant create table to 用户名; grant create tablespace to 用户名; …

Win10 该如何设置FTP呢,详细设置步骤

复印&#xff0c;打印&#xff0c;扫描的日常操作是每个办公人员的必备技能&#xff0c;我们来了解一下扫描至FTP的具体操作方法。 要使用FTP功能扫描文件到电脑&#xff0c;首先要需要一台可以接收文件的FTP服务器&#xff0c;这个服务器我们可以借助第三方软件搭建&#xff0…

数值的加减会改变python中id,在python中调用Nan值并更改为数字

ix已弃用&#xff0c;请不要使用它。在选项1我会用np.where-df df.assign(pronp.where(df.pro.isnull(), df.property_type, df.pro))dfid property_type1 property_type pro0 1 Condominium 2 2.01 2 Farm 14 14.02 3 House 7 7.03 4 Lots/Land 15 15.04 5 Mobile/Manufactur…

Linux和Windows操作系统有什么区别?

目录 1、Linux系统的优缺点 2、Linux系统与Windows系统的区别 在所有操作系统中&#xff0c;Windows系统属于最多用户使用的操作系统&#xff0c;而这一次小编要来跟大家聊聊Linux系统&#xff0c;目前很多笔记本也已经开始预装Linux系统了。那么Linux系统有什么优缺点呢&#…

idea自动生成not null判断语句

自动生成not null这种if判断&#xff0c;在IDEA里有很多种办法&#xff0c;其中一种办法你可能没想到。 直接输入notnull并回车&#xff0c;IDEA就好自动生成if判断了

C#三层开发做学生管理系统

1.定义各个层 2.添加各个层之间的引用 DAL 层调用Model BLL层调用DAL和Model UI层调用BLL和Model层 Model层供各个层调用 3.根据数据库建立实体类,每张表对应一个实体类 4.在DAL层调用MyTool类和SQLhelper类,添加system.Configuration 引用 并编写app.config 在SqlHelper类调用…