当前位置:网站首页>26. 如何判断一个对象是否存活?(或者GC对象的判定方法)?
26. 如何判断一个对象是否存活?(或者GC对象的判定方法)?
2022-08-02 03:58:00 【Jasonakeke】
如何判断一个对象是否存活?或者GC对象的判定方法?
这个问题,面试被问到的概率还是很大的。以下关于 如何判断一个对象是否存活 的回答,完全参照《深入理解Java虚拟机》一书,有需要的可以看书学习。以下是题目解析
判断对象是否存活的算法包括:
引用计数算法
可达性分析算法
问题的回答就是通过引用计数算法或者可达性分析算法去判断一个对象是否存活,下面开始具体描述这两种算法。
引用计数算法(Reference Counting)
给对象中添加一个引用计数器,每当有一个地方引用它时,计数器加1;当引用失效时,计数器值减1;任何时刻计数器为0的对象就是不能再被引用的。
例如Object-C,Python语音使用引用计数算法进行内存管理。Java虚拟机没有选用引用计数器算法来管理内存,其中最主要的原因是它很难解决对象之间相互循环引用的问题。
对象循环引用代码示例:
public class ReferenceCountingGC {
public Object instance = null;
public static void testGC() {
ReferenceCountingGC objA = new ReferenceCountingGC();
ReferenceCountingGC objB = new ReferenceCountingGC();
objA.instance = objB;
objB.instance = objA;
objA = null;
objB = null;
// 假设在这行发生GC, objA 和 objB是否能被回收?
System.gc();
}
}
对象objA和objB都有字段instance,赋值令 objA.instance = objB及objB.instance = objA,除此之外,这两个对象再无任务引用,实际上这两个对象已经不可能再被访问,但是它们因为相互引用着对方,导致它们的引用计数都不为0,于是引用计数算法无法通知GC收集器回收它们。

可达性分析算法(Reachability Analysis)
可达性分析算法的基本思路是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Root没有任何引用链相连时,则证明此对象是不可用的。
生存还是死亡
即使在可达性分析算法中不可达的对象,也并非是“非死不可”的,这时候它们暂时处于“缓刑”阶段,要真正宣告一个对象死亡,至少要经历两次标记过程:如果对象在进行可达性分析后发现没有与GC Roots相连接的引用,那它将会被第一次标记并且进行一次筛选,筛选的条件是此对象是否是否有必要执行finalize()方法。当对象没有覆盖finalize()方法,或者finalize()方法已经被虚拟机调用过,虚拟机将这两种情况都视为“没有必要执行”。
如果这个对象被判定为有必要执行finalize()方法,那么这个对象将会放置在一个叫做F-Queue的队列之中。并在稍后由一个虚拟机自动建立的,低优先级的Finalizer线程去执行它。这里所谓“执行”是指虚拟机会触发这个方法,但并不承诺会等待它运行结束,这样做的原因是,如果有一个对象在finalize()方法中执行缓慢,或者发生死循环,将可能会导致F-Queue队列中其他对象永久处于等待,甚至导致整个内存回收系统崩溃。
finalize()方法是对象逃脱死亡命运的最后一次机会,稍后GC将对F-Queue中的对象进行第二次小规模的标记,如果对象这个时候,未被重新引用,那它基本上就真的被回收了。
回收方法区
Java虚拟机规范中确实说过可以不要求虚拟机在方法区中实现垃圾回收,而且在方法区中进行垃圾回收的“性价比”一般比较低,方法区的垃圾收集主要回收两部分内容:废弃的常量和无用的类。
废弃的常量,以常量池中字面量的回收为例,假如一个字符串“abc”已经进入常量池中,但是当前系统已经没有任何一个String对象叫做“abc”的,也没有任何其他地方引用这个字面量,这个“abc”常量就会被清理出常量池。
判断一个无用的类需要同时满足下面3个条件才能算是“无用的类”
- 该类的所有实例都已经被回收
- 加载该类的ClassLoader已经被回收
- 该类对应的java.lang.Class对象已经没有任何地方被引用,无法在任何地方通过反射访问该类的方法。
边栏推荐
- 深蓝学院-视觉SLAM十四讲-第四章作业
- 字典基本操作方法
- OpenPCDet environment configuration of 3 d object detection and demo test
- 科研笔记(六) 基于环境感知的室内路径规划方法
- 如何让固定点的监控设备在EasyCVR平台GIS电子地图上显示地理位置?
- [Win11] PowerShell cannot activate Conda virtual environment
- 日本痴汉打赏女主播1.5亿,结果。。。
- 高等数学(第七版)同济大学 总习题三(后10题) 个人解答
- 深度剖析-class的几个对象(utlis,component)-瀑布流-懒加载(概念,作用,原理,实现步骤)
- 多主复制下处理写冲突(3)-收敛至一致的状态及自定义冲突解决逻辑
猜你喜欢
随机推荐
并发性,时间和相对性(1)-确定前后关系
节流阀和本地存储
MapFi paper structure organization
Deep Blue Academy - Fourteen Lectures of Visual SLAM - Chapter 4 Homework
列表总结
Jetson Nano 2GB Developer Kit 安装说明
被大厂强制毕业,两个月空窗期死背八股文,幸好上岸,不然房贷都还不上了
ScholarOne Manuscripts submits journal LaTeX file and cannot convert PDF successfully!
热爱和责任
2022-08-01:以下go语言代码输出什么?A:panic;B:5;C:6;D:编译错误。 package main import ( “fmt“ ) func main() {
单目三维目标检测之CaDDN论文阅读
[Win11] PowerShell无法激活Conda虚拟环境
深蓝学院-视觉SLAM十四讲-第七章作业
多主复制下处理写冲突(4)-多主复制拓扑
无主复制系统(1)-节点故障时写DB
Qt编写物联网管理平台49-设备模拟工具
分布式系统的一致性与共识(1)-综述
吴恩达机器学习系列课程笔记——第八章:神经网络:表述(Neural Networks: Representation)
MapFi论文架构整理
jetracer_pro_2GB AI Kit system installation instructions









