前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >探究Java中的引用

探究Java中的引用

作者头像
王金龙
发布于 2020-03-05 12:38:01
发布于 2020-03-05 12:38:01
1.1K0
举报
文章被收录于专栏:王金龙的专栏王金龙的专栏

探究Java中的四种引用

从JDK1.2版本开始,Java把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期。这四种级别由高到低依次为:强引用、软引用、弱引用和虚引用。本篇就来详细探究一下这四种引用的机制:

  • 强引用
  • 软引用
  • 弱引用
  • 虚引用
  • 详解ReferenceQueue与Reference

强引用

强引用是最普遍的引用,一般通过new关键字来创建出来的对象引用都属于强引用,比如Object o = new Object()。

如果一个对象具有强引用,它就不会被垃圾回收器回收。即使当前内存空间不足,JVM也不会回收它,而是抛出 OutOfMemoryError 错误,使程序异常终止。如果想中断强引用和某个对象之间的关联,可以显式地将引用赋值为null,这样一来的话,JVM在合适的时间就会回收该对象。

软引用

在使用软引用时,如果内存的空间足够,软引用就能继续被使用,而不会被垃圾回收器回收;只有在内存空间不足时,软引用才会被垃圾回收器回收。软引用最长被用作内存敏感型的内存缓存。

创建一个软引用的代码示例:

1

SoftReference<String> soft = new SoftReference<>("World");

SoftReference类的结构如下:

1 2 3 4 5 6 7 8 9

java.lang.ref.SoftReference#SoftReference(T) java.lang.ref.SoftReference#SoftReference(T, java.lang.ref.ReferenceQueue<? super T>) java.lang.ref.SoftReference#get java.lang.ref.SoftReference#clock java.lang.ref.SoftReference#timestamp

  • 前两个是构造函数,后面会详细介绍ReferenceQueue;
  • get方法用于获取这个软引用所指向的对象,如果这个对象已经清除或者被GC收集,那么就返回null;
  • clock属性是一个static的long型时间戳,由GC线程进行GC的时候更新;
  • timestamp属性也是一个时间戳,每次在调用get方法的时候会对其进行更新,JVM用这个属性用于帮助收集和清理软引用。

弱引用

如果一个对象只具有弱引用,当 JVM 进行垃圾回收时,只要GC线程检测到了,无论当前内存空间是否充足,都会将其回收。不过由于垃圾回收器是一个优先级较低的线程,所以并不一定能迅速发现弱引用对象。弱引用通常用于实现规范化映射。

创建一个弱引用的代码示例:

1

WeakReference<String> weakName = new WeakReference<String>("hello");

WeakReference类的结构如下:

1 2 3

java.lang.ref.WeakReference#WeakReference(T) java.lang.ref.WeakReference#WeakReference(T, java.lang.ref.ReferenceQueue<? super T>)

只是提供了两个构造函数,后一个构造函数传入了一个ReferenceQueue对象。

虚引用

顾名思义,就是形同虚设的引用,如果一个对象仅持有虚引用,那么它相当于没有引用,在任何时候都可能被垃圾回收器回收。

创建虚引用的代码示例:

1 2 3

ReferenceQueue<String> queue = new ReferenceQueue<String>(); PhantomReference<String> pr = new PhantomReference<String>(new String("hello"), queue);

PhantomReference类的结构如下:

1 2 3

java.lang.ref.PhantomReference#PhantomReference(T, ReferenceQueue<? super T>) java.lang.ref.PhantomReference#get

  • 只有一个带有ReferenceQueue参数的构造函数,也就是虚引用一定要和引用队列一起使用;
  • 同时其get方法也有点特殊,因为虚引用的引用对象相当于没有引用,所以其get方法总是返回null。

详解ReferenceQueue与Reference

引用队列可以与软引用、弱引用以及虚引用一起配合使用,当垃圾回收器准备回收一个对象时,如果发现它还有引用,那么就会在回收对象之前,把这个引用加入到与之关联的引用队列中去。程序可以通过判断引用队列中是否已经加入了引用,来判断被引用的对象是否将要被垃圾回收,这样就可以在对象被回收之前采取一些必要的措施。

与软引用、弱引用不同,虚引用必须和引用队列一起使用。

ReferenceQueue实现了一个队列的入队(enqueue)和出队(poll还有remove)操作,内部元素就是Reference。ReferenceQueue名义上是一个队列,但内部并没有实际的存储结构,它的存储是依赖于内部节点之间的关系来实现的。看一下ReferenceQueue实现中用到的属性:

1 2 3 4 5 6 7 8 9 10 11 12 13

static ReferenceQueue<Object> NULL = new Null<>(); static ReferenceQueue<Object> ENQUEUED = new Null<>(); static private class Lock { }; private Lock lock = new Lock(); private volatile Reference<? extends T> head = null; private long queueLength = 0;

其实就是一个增加了同步操作的链表的设计,通过head属性来找到链表头,每个链表节点,即Reference对象,都有一个next属性来找到下一个节点。

刚才分析四种引用的时候看到,java.lang.ref.Reference 为 软(soft)引用、弱(weak)引用、虚(phantom)引用的父类。那我们再来看一下Reference类的实现中用到的属性:

1 2 3 4 5 6 7 8 9 10 11 12 13

private T referent; /* Treated specially by GC */ volatile ReferenceQueue<? super T> queue; volatile Reference next; transient private Reference<T> discovered; /* used by VM */ static private class Lock { } private static Lock lock = new Lock(); private static Reference<Object> pending = null;

Reference作为ReferenceQueue中的节点,定义了next属性来指向下一个节点,referent为实际指向的对象,pending存储等待被放入ReferenceQueue的引用对象;discovered表示要处理的下一个对象。

Reference类还定义了一个ReferenceHandler线程。

1 2 3 4 5

java.lang.ref.Reference.ReferenceHandler#ReferenceHandler java.lang.ref.Reference.ReferenceHandler#ensureClassInitialized java.lang.ref.Reference.ReferenceHandler#run

这个线程在Reference类的static的构造块中启动,并且被设置为最高优先级和daemon状态。此线程要做的事情就是不断的检查pending属性是否为null,如果pending不为null,则将pending进行enqueue,否则线程进入wait状态。

由此可见,pending是由jvm来赋值的,当Reference内部的referent对象的可达状态改变时,jvm会将Reference对象放入pending链表。并且这里enqueue的队列是我们在初始化(构造函数)Reference对象时传进来的queue,如果传入了null( 实际使用的是ReferenceQueue.NULL ),则ReferenceHandler则不进行enqueue操作,所以只有非RefernceQueue.NULL的queue才会将Reference进行enqueue。

ReferenceQueue作为 JVM GC与上层Reference对象管理之间的一个消息传递方式,它使得我们可以对所监听的对象引用可达发生变化时做一些处理。

关注我的公众号,获取更多关于面试、技术的文章及福利资源。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-03-03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
1 条评论
热度
最新
腾讯云TRTC支持Unity开发吗?
腾讯云TRTC支持Unity开发吗?
回复回复点赞举报
推荐阅读
实时音视频 TRTC 常见问题汇总---集成接入篇
TRTC 的日志默认压缩加密,后缀为 .xlog。日志是否加密是可以通过 setLogCompressEnabled 来控制,生成的文件名里面含 C(compressed) 的就是加密压缩的,含 R(raw) 的就是明文的。
腾讯视频云-Zachary
2019/11/01
14.5K1
实时音视频 TRTC 常见问题汇总---集成接入篇
实时音视频 TRTC 常见问题汇总---质量篇
如下代码所示,播放远端观众的画面渲染模式选择 TRTC_VIDEO_RENDER_MODE_FIT模式, 当渲染控件 View 的宽高比与视频宽高此不一致时,有黑边情况。
腾讯视频云-Zachary
2021/10/10
4.1K0
实时音视频 TRTC 常见问题汇总---咨询问题篇
TRTC 是腾讯云基于 QQ 十多年来在音视频通话技术上积累,结合腾讯浏览服务 TBS WebRTC 能力与腾讯实时音视频 SDK ,为客户提供多平台互通高品质可定制化的 实时音视频互通服务 解决方案。 (1)您可以通过“crtl+F”(win)、“command+F”(mac)搜索关键字。 (2)若没有您想要的问答,欢迎在评论区提问、留言和交流,笔者会定期解答疑惑。 (3)最新产品动态与变更以官网文档为准。
TRTC小百科
2021/09/16
8.9K2
TRTC零基础上手 -- 码上视频推流篇
视频画面来自于摄像头,TRTC SDK会采集摄像头的画面,然后编码打包发送至云端链路,开发者只需要调用采集接口和设置编码器视频参数(码率、分辨率、帧率等)完成摄像头画面的采集。
天上云间
2022/01/13
2.4K0
实时音视频SDK,如何实现类似微信的纯语音通话功能?
实时音视频TRTCSDK适用的业务场景是视频会议、坐席视频、在线教育等,如果您希望实现类似微信的语音通话、语音会议功能,TRTCSDK也是支持的,只需要微调几个参数就可以实现,将采集音视频的api,换成只采集音频。
腾讯云-chaoli
2019/03/05
8.2K2
实时音视频SDK,如何实现类似微信的纯语音通话功能?
实时音视频(TRTC)使用前摄像头进行视频通话,本地预览和远端观众画面是左右颠倒?
使用前摄像头进行视频通话,会有镜像效果,所以本地预览和远端观众画面是左右颠倒。如果开发者想让两端画面一致,TRTCSDK 提供两个接口供你使用选择使用
腾讯云-yyuanchen
2019/07/25
3.6K1
腾讯云实时音视频客户端实现A+B->A和A+B->C混流方式
上一篇文章介绍了腾讯云实时音视频的两种混流方式分别是A+B->A和A+B->C,本文重点介绍,客户端如何实现这两种混流的方式,代码附上
singleli
2022/11/28
1.5K0
【最佳实践】巡检项:实时音视频 (TRTC) 原生平台 SDK 的进入同一房间的用户是否设定相同的 应用场景(TRTCAppScene)参数
在视频通话场景(VideoCall),出现Android端推流绿屏现象,具体表现是,房间内其他用户拉流观看,显示该用户的画面出现绿色色块,并且在进房后一直持续出现。这种现象不是该用户每次进房都出现,是偶现的。
jackwlchen
2022/04/29
9080
实时音视频 TRTC 常见问题汇总---咨询问题篇
支持的平台包括 iOS、Android、Windows(C++)、Windows(C#)、Mac、Web、Electron、微信小程序、Flutter,更多详情请参见 平台支持。
腾讯视频云-Zachary
2019/11/01
13.3K0
实时音视频 TRTC 常见问题汇总---咨询问题篇
你问我答 | 实时音视频TRTC(2021年8月-10月)
实时音视频TRTC 你问我答 第2季 本期共解答10个问题 Q1:TRTC通话,实现大小屏切换,类似微信通话效果,点击自己的画面和对方的画面展示位置互换。 支持大小屏切换,使用updateView功能,但需要给TXCloudVideoView调用addview添加一个textureview。 解决方案: 通话过程中,保证双方通话画面正常; 直接调用stop,再调用start,会有一段时间黑屏; 直接调用updateView对调,会导致远端画面不显示,或者没有效果; updateView
腾讯云音视频
2021/11/26
1.2K0
你问我答 | 实时音视频TRTC(2021年5月-7月)
实时音视频TRTC 你问我答 第1季 本期共解答10个问题 Q1:移动端(Andriod/iOS)支持哪几种系统音量模式? 支持2种系统音量类型,即通话音量类型和媒体音量类型: 通话音量,手机专门为通话场景设计的音量类型,使用手机自带的回声抵消功能,音质相比媒体音量类型较差, 无法通过音量按键将音量调成零,但是支持蓝牙耳机上的麦克风。 媒体音量,手机专门为音乐场景设计的音量类型,音质相比于通话音量类型要好,通过通过音量按键可以将音量调成零。使用媒体音量类型时,如果要开启回声抵消(AEC
腾讯云音视频
2021/08/30
1.3K0
TRTC零基础上手 -- 码上视频订阅篇
当作为拉流端,在远端推流后即可开始拉流,为了用户体验,建议按照规范要求,在收到SDK的事件回调后开始拉流,并在控件上显示远端画面
天上云间
2022/01/19
1.3K0
实时音视频 TRTC 常见问题汇总---小程序篇
如有更多需求,或希望深度合作,可以 提交工单 或致电4009100100联系我们。
腾讯视频云-Zachary
2021/09/21
5.8K0
实时音视频 TRTC 常见问题汇总---小程序篇
实时音视频V2版本,如何进行纯音频旁路直播
实时音视频TRTCSDK适用的业务场景是视频会议、坐席通话、在线教育等,也可以实现类似微信的语音通话、语音会议功能,
腾讯云-chaoli
2019/03/13
3.5K0
实时音视频V2版本,如何进行纯音频旁路直播
TRTC学习之旅(四)-- 用electron实现视频聊天室
前面我们已经学习过在web端用TRTC实时音视频SDK实现了多人会议室和互动直播模式,今天我们学习一下在桌面应用层用electron实现视频聊天。
黑眼圈云豆
2020/07/08
4.9K7
TRTC 视频旋转场景方案
在网络会议、双人视频通话等场景时,将手机横屏、竖屏放置场景下,实现本地和远端都可以看到正常的画面效果。
erickyan
2022/04/12
1.8K0
TRTC 视频旋转场景方案
实时音视频 TRTC 常见问题汇总---WebRTC篇
TRTC Web SDK 对浏览器的详细支持度,您可以查看 TRTC Web SDK 对浏览器支持情况。
腾讯视频云-Zachary
2019/11/15
23.2K3
实时音视频 TRTC 常见问题汇总---WebRTC篇
Android TRTC 推自定义采集的视频数据
如果开发者想在 TRTC 中集成第三方美颜库来实现美颜、滤镜等功能,第三方库的美颜功能输入数据格式支持有 camera 的原始数据(YUV 数据)、纹理数据(Textureid)。开发者想实现该功能,需要采用自定义采集视频数据接口,然后复用 LiteAVSDK 的编码和推流功能。
腾讯云-chaoli
2019/07/07
1.9K0
Android TRTC 推自定义采集的视频数据
iOS音视频接入 - TRTC接入实时视频通话
(前面我们已经了解TRTC的基本架构和功能,现在我们就来接入实时视频通话功能,此功能和微信的一对一视频通话是一致的,需要两个角色,一个角色是主动呼叫、一个为呼叫接听,结合使用场景我们来接入此功能。
小明同学接音视频
2020/10/13
6.3K0
iOS音视频接入 - TRTC接入实时视频通话
产品动态 | TRTC React Native SDK上线啦
React Native 是一个使用React和应用平台的原生功能来构建 Android 和 iOS 应用的开源框架。通过 React Native,您可以使用 JavaScript 来访问移动平台的 API,以及使用 React 组件来描述 UI 的外观和行为:一系列可重用、可嵌套的代码。 TRTC React Native SDK 是基于腾讯云 iOS/Android 平台的 TRTC SDK 进行封装的,架构图整体跟Flutter类似。 TRTC React Native sdk类文件说
腾讯云音视频
2021/11/22
1.2K0
推荐阅读
相关推荐
实时音视频 TRTC 常见问题汇总---集成接入篇
更多 >
LV.1
这个人很懒,什么都没有留下~
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档