十分钟理解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中的弱引用

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

  1. java弱引用怎么手动释放,Java 如何有效地避免OOM:善于利用软引用和弱引用

    前言 想必很多朋友对OOM(OutOfMemory)这个错误不会陌生,而当遇到这种错误如何有效地解决这个问题呢?今天我们就来说一下如何利用软引用和弱引用来有效地解决程序中出现的OOM问题. 一.了解 ...

  2. 十分钟理解javascript中的this对象

    最近在参加的几场面试中都涉及到了对于js中this对象的理解,那么怎样去理解this呢?这里针对不同的场景通过代码来帮助我们理解好this. this到底指向什么? this指向什么呢?一言以蔽之: ...

  3. python引用传递产生的问题_理解Python中传递值和引用时出现问题

    我可以看到三个基本的Python概念,它们可以为这个问题提供一些启示: 1)首先,来自可变对象的赋值,如self.foo = arg1 就像复制指针(而不是所指向的值):self.foo和{}是相同的 ...

  4. android中sp的意义_两分钟理解Android中SP与DP的区别

    从一开始写Android程序,就被告知这些常识 长度宽度的数值要使用dp作为单位放入dimens.xml文件中 字体大小的数值要使用sp作为单位,也放入dimens.xml文件中 然后,就没有然后了, ...

  5. 【Unity3D Shader编程】之十 深入理解Unity5中的Standard Shader(二)屏幕油画特效的实现

    本系列文章由@浅墨_毛星云 出品,转载请注明出处.   文章链接: http://blog.csdn.net/poem_qianmo/article/details/49719247 作者:毛星云(浅 ...

  6. Unity3D Shader编程】之十 深入理解Unity5中的Standard Shader(二)屏幕油画特效的实现

    本系列文章由@浅墨_毛星云 出品,转载请注明出处.   文章链接: http://blog.csdn.net/poem_qianmo/article/details/49719247 作者:毛星云(浅 ...

  7. java的弱引用_深入理解Java中的弱引用

    不久之前,我面试了一些求职Java高级开发工程师的应聘者.我常常会面试他们说,"你能给我介绍一些Java中得弱引用吗?",如果面试者这样说,"嗯,是不是垃圾回收有关的?& ...

  8. 理解Java中的弱引用(Weak Reference)

    理解Java中的弱引用(Weak Reference) 本篇文章尝试从What.Why.How这三个角度来探索Java中的弱引用,理解Java中弱引用的定义.基本使用场景和使用方法.由于个人水平有限, ...

  9. java的弱引用_理解Java中的弱引用(Weak Reference)

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

最新文章

  1. 从零开始学Win32平台缓冲区溢出(Part1)
  2. 新疆那些大学在计算机专业好,新疆哪些二本大学的计算机科学与技术专业最好?...
  3. Arthas 用户文档
  4. 一个常见的台式计算机有哪些硬件部分组成,台式电脑有哪些组成部分
  5. 当Node.js遇见Docker
  6. 怎么定义int_「C语言更新」C语言中如何来定义一个指针,并且对其进行初始化...
  7. visio2016 数据库模型图_数据库第七章--NoSQL数据库
  8. 1208_MISRA_C规范学习笔记_Rule 10.3 Rule 10.5
  9. 微生物组数据系统发育分析的方法
  10. 电脑计算机无法找到脚本文件夹,电脑弹出无法找到脚本文件怎么办
  11. 微博、微信朋友圈、QQ空间功能对比
  12. java 计算年龄_java实现简单年龄计算器
  13. python远程主机强迫关闭了_[转] python 远程主机强迫关闭了一个现有的连接 socket 超时设置 errno 10054...
  14. android 屏幕方向监听,Android如何监听屏幕旋转
  15. 什么是BlockingQueue
  16. 2019秋招备战复习篇
  17. vsphere之vmotion精华
  18. 本科计算机 出国可以学营养学吗,美国营养学专业哪些大学比较好 十所美国营养...
  19. 跨境电商 Shopee 的实时数仓之路
  20. 【猿哥学二建】第一周 考试准备

热门文章

  1. halcon/c++接口基础 之 构造函数与Halcon算子
  2. android 串口调试工具_树莓派通用串口通信实验
  3. 简易贪吃蛇小游戏java版_用GUI实现java版贪吃蛇小游戏
  4. 第3章 Python 数字图像处理(DIP) - 灰度变换与空间滤波3 -幂律变换、伽马变换
  5. 解决网站请求速度慢的一些方法
  6. python 2 类与对象
  7. js 实时监听input中值变化
  8. C#用Zlib压缩或解压缩字节数组
  9. Android service 小研究
  10. java中filter的用法