首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

java 的四种引用类型

概述

在 java 对象存活判定算法的文章中,我们介绍了java 引用的分类。=

本文中,我们深入讨论一下四种引用究竟有什么区别,以及如何指定具体的引用方式。

正如在上面日志中介绍的,在Java中,虽然不需要程序员手动去管理对象的生命周期,但是如果希望某些对象具备一定的生命周期的话(比如内存不足时JVM就会自动回收某些对象从而避免OutOfMemory的错误)就需要用到软引用和弱引用了。

强引用

代码中普遍存在的,Object obj = new Object() 所创建的引用,只要强引用存在,垃圾收集器就永远不会回收被引用对象。

当内存不足的时候,jvm 就会抛出 OutOfMemory 错误,而不会回收强引用的对象。

强引用的断裂

只有以下两种方式可以让强引用中断,从而让 jvm 在合适的时间就会回收该对象。

1. 显式赋值为 null 会中断强引用和对象之间的关联

2. 在一个方法内部创建的对象,由于强引用保存在栈上,所引用的对象保存在堆空间中,当这个方法运行完成就会退出方法栈,从而让强引用断裂

软引用

如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。

通常,软引用可用来实现内存敏感的高速缓存。

创建软引用

适用场景

正如我们前面说的,软引用最常用的场景是高速缓存。

例如对于已经加载过的网页,如果我们通过强引用来实现,在进入新页面时,老页面就有两种选择:主动赋值为 null 或什么都不做。

如果赋值为 null,那么点击回退就必须重新加载原网页,造成体验不佳,而如果什么都不做,大量的加载过的网页停留在内存中,最终就会造成 OutOfMemory 错误。

这时,通过软引用,让已加载过的页面在内存不足时被自动回收,只要内存充足就可以任意回退而不需要重新加载,就是一个非常好的选择。

软引用队列

软引用可以配合引用队列进行使用,当软引用占有的对象被回收后,jvm 会将该软引用对象放入引用队列中。

通过软引用队列,我们可以清楚地知道程序中已有的软引用哪些已经被回收掉了。

通过软引用队列实现软引用缓存

我们结合软引用与软引用队列来实现一个 KV 缓存。

缓存接口

我们先来定义最基本的 KV 缓存规范接口。

只需要一个 get 接口和一个 set 接口即可。

软引用的实现

软引用只是对一个对象的引用,我们需要 K-V 的组合,因此仅仅使用软引用是不够的,需要对软引用添加额外信息,因此我们继承软引用来实现自己的软引用。

软引用缓存

我们通过 ConcurrentHashMap 实现了一个 K-V 存储,同时通过 ExtraInfoReference 设置 info 成员为 key,将软引用设置为 value 的方式记录了所有在缓存中的数据。

这样,当我们调用 get 方法发现 value 为 null 的时候,我们可以轻松地通过软引用队列来对缓存进行清理。

需要注意的是,调用 get 方法时,value = refValue.get() 会将软引用转化为强引用。

弱引用

与软引用相比,只具有弱引用的对象拥有更短暂的生命周期,不管当前内存空间是否充足,只要进行垃圾回收,弱引用的对象都会被回收。

通常只有创建时不一定会被使用到的对象应该设置为弱引用,只有当被使用到时,即通过赋值,转化为强引用,例如回调方法中的对象是一个典型场景,回调方法通常是通过匿名内部类实现的,如果他们持有外部类的强引用就造成了内存泄露。

弱引用队列

与软引用一样,也可以通过传入 ReferenceQueue 对象指定销毁后存放的队列。

虚引用

虚引用也称为“幽灵引用”或“幻影引。

无法通过虚引用获取一个对象的实例,因此它的存在只能用来跟踪垃圾回收器的回收活动。

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

总结

四种引用类型及生存时间

参考资料

深入理解 Java 虚拟机 — jvm 高级特性与最佳实践(第 2 版)

https://www.cnblogs.com/gudi/p/6403953.html。

https://blog.csdn.net/jiangjiajian2008/article/details/52929843。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180625G0G1Q100?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券