Java的四种引用

简介: Java里的四种引用类型:强引用、软引用、弱引用和虚引用。

Java中存在四种引用:

  • StrongReference(强引用)
  • SoftReferenc(软引用)
  • WeakReferenc(弱引用)
  • PhantomReference(虚引用)

强引用

java中的引用默认就是强引用,任何一个对象的赋值操作就产生了对这个对象的强引用

如:Object obj = new Object();

特性只要有强引用存在,被引用的对象就不会被垃圾回收。当内存不足时,抛出 OutOfMemoryError 异常。

软引用

SoftReference

软引用是用来描述一些还有用,但非必须的对象。

只有在内存不足的情况下,被引用的对象才会被回收。

弱引用

WeakReference

也是用来描述那些非必须对象的,但是它的强度比软引用更弱一些。

weekReference引用的对象只要垃圾回收执行,就会被回收,而不管是否内存不足。

示例

image.png

我们在操作threadlocal的时候,是定义了一个静态变量:

static ThreadLocal<String> threadlocal = new ThreadLocal<>()

此时threadlocal引用是强引用。

然后我们通过set操作,以 threadlocal 为键,存入threadlocalmap里的数组table[i],这时 table[i] 内的key指向theadlocal的引用就是弱引用,当gc(垃圾回收)的时候,这个引用就会被回收,然后key就变成了null。

虚引用

  • 判断对象是否被回收,通过检查引用队列中是否包含虚引用来判断是否被回收。
  • 当对象被回收的时候,在引用队列判断的时候,可以根据需要做一些事情,比如资源清理等等。

Phantom Reference,/ˈfæntəm/

“虚引用”顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。

虚引用主要用来跟踪对象被垃圾回收器回收的活动。

虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列 (ReferenceQueue)联合使用,当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中

不能单独使用也不能通过它访问对象,虚引用必须和引用队列(ReferenceQueue)联合使用。

虚引用的主要作用是跟踪对象被垃圾回收的状态,仅仅是提供了一种确保对象被finalize以后,做某些事情的机制。PhantomRefernce的get方法总是返回null,因此无法访问对应的引用对象,其意义在于说明一个对象已经进入finalization阶段,可以被gc回收,用来实现比finalization机制更灵活的回收操作。

换句话说,设置虚引用关联的唯一目的,就是在这个对象被收集器回收的时候收到一个系统通知或者后续添加进一步处理(允许我们在对象被销毁后,做一些我们自己想做的事情)。Java技术允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。

虚引用的主要作用是跟踪对象被垃圾回收器回收的活动。 它与软引用和弱引用的一个关键区别在于,虚引用必须与引用队列(ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现该对象还有虚引用,就会把对应的虚引用加入到与之关联的引用队列中。这样,通过检查引用队列中是否加入了虚引用,可以了解被引用对象是否将要被垃圾回收器回收,并据此执行一些必要的操作,如资源回收。

此外,虚引用的这种特性使得它特别适用于需要监控对象生命周期并进行相应资源管理的场景,例如在对象被回收前执行清理操作或其他逻辑。

它的作用在于跟踪垃圾回收过程,在对象被收集器回收时收到一个系统通知。 当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在垃圾回收后,将这个虚引用加入引用队列,在其关联的虚引用出队前,不会彻底销毁该对象。 所以可以通过检查引用队列中是否有相应的虚引用来判断对象是否已经被回收了。

如果一个对象没有强引用和软引用,对于垃圾回收器而言便是可以被清除的,在清除之前,会调用其finalize方法,如果一个对象已经被调用过finalize方法但是还没有被释放,它就变成了一个虚可达对象。

与软引用和弱引用不同,显式使用虚引用可以阻止对象被清除,只有在程序中显式或者隐式移除这个虚引用时,这个已经执行过finalize方法的对象才会被清除。想要显式的移除虚引用的话,只需要将其从引用队列中取出然后扔掉(置为null)即可。

因为设置的虚拟机堆大小比较小,所以创建一个100k的对象时直接进入了老年代,等到发生Full GC时才会被扫描然后回收。

适用场景

使用虚引用的目的就是为了得知对象被GC的时机,所以可以利用虚引用来进行销毁前的一些操作,比如说资源释放等。

事实上,虚引用有一个很重要的用途就是用来做堆外内存的释放,DirectByteBuffer就是通过虚引用来实现堆外内存的释放的。

目录
相关文章
|
安全 网络安全 Windows
LabVIEW把VI发布到网页上
LabVIEW把VI发布到网页上
151 0
|
Java 数据库 数据安全/隐私保护
JSP旅游景点网站系统myeclipse开发计算机程序web结构java编程网页源码
JSP 旅游景点及旅游线路管理系统 是一套完善的web设计系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。
156 0
|
搜索推荐
冒泡排序,选择排序,直接插入排序
🐰冒泡排序 🐰选择排序 🐰直接插入排序
|
机器学习/深度学习 自然语言处理
论文赏析[ICLR18]联合句法和词汇学习的神经语言模型(一)
一般来说,自然语言是由词汇和句法组成的,但是标准的语言模型一般都只用RNN对词汇进行建模,句法信息都是隐式的学习到的,没有办法显式地拿出来使用。所以本文提出的语言模型的变体可以结合结构上的attention,在中间过程中学习到结构信息,然后这层结构信息可以拿来生成句法树,用来做无监督的句法分析。
299 0
论文赏析[ICLR18]联合句法和词汇学习的神经语言模型(一)
|
JavaScript 前端开发 API
产品经理又开始为难我了???我。。。。(二)
插件开发——配置右键菜单 这个功能描述大概就是,你在写的时候突然要上传,直接点击鼠标右键,然后直接选择图片。对就是这个简单的东西,做东西需要从用户的角度考虑,一定要爽,能省一步是一步。呵呵哈哈哈 这个配置其实就是在 还是在刚才的「package.json」 上继续配置: "menus": { "editor/context": [ { "when": "editorFocus", "command": "extension.choosedImage", "group": "navigation" } ] w
产品经理又开始为难我了???我。。。。(二)
|
机器学习/深度学习 人工智能 算法
球队“食物链”
c++天梯赛算法题
ASCII对应码表(键值)(8)
ASCII对应码表(键值)(8)
166 0
AIoT真正向万亿级市场落地的关键是什么?
要想实现万物互联,更关键的一环在于落地场景。
681 0
|
弹性计算 关系型数据库 分布式数据库
使用PolarDB和ECS搭建门户网站
PolarDB采用存储和计算分离的架构,所有计算节点共享一份数据,提供分钟级的配置升降级、秒级的故障恢复、全局数据一致性和免费的数据备份容灾服务。PolarDB既融合了商业数据库稳定可靠、高性能、可扩展的特征,又具有开源云数据库简单开放、自我迭代的优势,例如PolarDB MySQL性能最高可以提升至MySQL的6倍,而成本只有商用数据库的1/10。集群架构,计算与存储分离。
|
算法 C# 计算机视觉
Win8 Metro(C#)数字图像处理--2.51图像统计滤波算法
原文:Win8 Metro(C#)数字图像处理--2.51图像统计滤波算法  [函数名称]   图像统计滤波   WriteableBitmap StatisticalFilter(WriteableBitm...
1156 0