JVM:判断一个Java对象能否存活
前言
- 如何判断一个Java对象能否存活对于垃圾回收、防止内存泄漏等十分重要
- 本文将全面讲解判断
Java
对象存活的方式,希望你们会喜欢
在接下来的日子,我会推出一系列讲解
JVM
的文章,具体如下;感兴趣可持续关注Carson_Ho的安卓开发笔记
示用意
目录
示用意
1. 判断方式
- 垃圾收集器对
Java
堆里的对象 能否进行回收的判断原则:Java
对象是存活 or 死亡
判断对象为死亡才会进行回收
- 在
Java
虚拟机中,判断对象能否存活有2种方法:- 引用计数法
- 引用链法(可达性分析法)
下面会进行详细详情。
2. 引用计数法
2.1 方式形容
- 给
Java
对象增加一个引用计数器 - 每当有一个地方引用它时,计数器 +1;引用失效则 -1;
2.2 判断对象存活原则
当计数器不为 0 时,判断该对象存活;否则判断为死亡(计数器 = 0)。
2.3 优点
- 实现简单
- 判断高效
2.4 缺点
- 无法处理 对象间相互循环引用 的问题
即该算法存在判断逻辑的漏洞
- 具体形容
<-- 背景 -->// 对象objA 和 objB 都有字段 name// 两个对象相互进行引用,除此之外这两个人对象没有任何引用objA.name = objB;objB.name = objA;<-- 问题 -->// 实际上这两个对象已经不可能再被访问,应该要被垃圾收集器进行回收// 但由于他们相互引用,所以导致计数器不为0,这导致引用计数算法无法通知垃圾收集器回收该两个对象
正因为该算法存在判断逻辑漏洞,所以 Java
虚拟机没有采用该算法判断Java
能否存活。
3. 引用链法(可达性分析法)
- 很多主流商用语言(如
Java
、C#
)都采用 引用链法 判断Java
对象能否存活。 - 含3个步骤:
- 可达性分析
- 第一次标记 & 挑选
- 第二次标记 & 挑选
3.1 可达性分析
a. 方式形容
将一系列的 GC Roots
对象作为起点,从这些起点开始向下搜索。
- 可作为
GC Root
的对象有:
1.Java
虚拟机栈(栈帧的本地变量表)中引用的对象
2.本地方法栈 中JNI
引用对象
3.方法区 中常量、类静态属性引用的对象- 向下搜索的路径 = 引用链
如下图:
示用意
b. 判断 对象能否可达 标准
当一个对象到 GC Roots
没有任何引用链相连时,则判断该对象不可达
没有任何引用链相连 =
GC Root
到对象不可达 = 对象不可用
示用意
特别注意
- 可达性分析 仅仅只是判断对象能否可达,但还不足以判断对象能否存活 / 死亡
- 当在 可达性分析 中判断不可达的对象,只是“被判刑” = 还没真正死亡
不可达对象会被放在”即将回收“的集合里。
- 要判断一个对象真正死亡,还需要经历两个阶段:
- 第一次标记 & 挑选
- 第二次标记 & 挑选
3.2 第一次标记 & 挑选
- 对象 在 可达性分析中 被判断为不可达后,会被第一次标记 & 准备被挑选
a. 不挑选:继续留在 ”即将回收“的集合里,等待回收;
b. 挑选:从 ”即将回收“的集合取出
- 挑选的标准:该对象能否有必要执行
finalize()
方法- 若有必要执行(人为设置),则挑选出来,进入下一阶段(第二次标记 & 挑选);
- 若没必要执行,判断该对象死亡,不挑选 并等待回收
当对象无
finalize()
方法 或者finalize()
已被虚拟机调用过,则视为“没必要执行”
3.3 第二次标记 & 挑选
当对象经过了第一次的标记 & 挑选,会被进行第二次标记 & 准备被进行 挑选
a. 方式形容
该对象会被放到一个 F-Queue
队列中,并由 虚拟机自动建立、优先级低的Finalizer
线程去执行 队列中该对象的finalize()
finalize()
只会被执行一次- 但并不承诺等待
finalize()
运行结束。这是为了防止finalize()
执行缓慢 / 中止 使得F-Queue
队列其余对象永久等待。
b. 挑选标准
在执行finalize()
过程中,若对象仍然没与引用链上的GC Roots
直接关联 或者 间接关联(即关联上与GC Roots
关联的对象),那么该对象将被判断死亡,不挑选(留在”即将回收“集合里) 并 等待回收
3.4 总结
3步骤 + 以下流程
示用意
4. 总结
- 本文全面讲解判断Java对象存活的方式
- 在接下来的日子,我会推出一系列讲解
JVM
的文章,具体如下;感兴趣可持续关注Carson_Ho的安卓开发笔记
示用意
请点赞!由于你的鼓励是我写作的最大动力!
相关文章阅读
Android开发:最全面、最易懂的Android屏幕适配处理方案
Android事件分发机制详解:史上最全面、最易懂
Android开发:史上最全的Android消息推送处理方案
Android开发:最全面、最易懂的Webview详解
Android开发:JSON简介及最全面解析方法!
Android四大组件:Service服务史上最全面解析
Android四大组件:BroadcastReceiver史上最全面解析
欢迎关注Carson_Ho的简书!
不定期分享关于安卓开发的干货,追求短、平、快,但却不缺深度。
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » JVM:判断一个Java对象能否存活