如何判断对象已死

本贴最后更新于 2704 天前,其中的信息可能已经物是人非

已死的对象就是不可能被任何途径使用的对象,有以下几种方法判断一个对象是否已经死了:

引用计数

给对象添加一个引用计数器,每当有一个地方引用他,计算器就加 1;当引用失效时,计数器减 1;任何时刻计数器为 0 的对象就是死的对象。
1. 这种方式被很多技术所采用,如 FlashPlayer(AS3)、Python 等,但是 Java 没有采用这种算法,原因是它很难解决对象之间相互循环引用的问题,例如 ObjectA.param=ObjectB,ObjectB.param=ObjectA,对象 A 和 B 相互引用但是除此之外他们再无任何其他引用,这样他们的引用计数都不为 0,永远不会被回收

根搜索

java 采用的是根搜索算法,这个算法的基本思路是通过一系列名为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所经过的路径称为引用链,当 GC Roots 到一个对象不可达时,这个对象就是不可用的
1. Java 中可作为 GC Roots 的对象包括:
1)虚拟机栈中引用的对象
2)方法区中类静态属性和常量引用的对象
3)本地方法栈中 Native 方法引用的对象

何为引用(和 ROOT 有关系)

简单描述引用就是一块内存中存储的数值代表的是另外一块内存的起始地址,则成这块内存代表着一个引用,这种描述很纯粹但是是不太正确的,可以作为理解时用
1. 引用分为强引用、软引用、弱引用、虚引用
1)强引用:如 Object obj=new Object();只要强引用存在,GC 肯定不会回收被引用的对象
2)软引用:非必需的对象,当系统要发生内存溢出之前,会把这些对象列入回收范围
3)弱引用:更加非必需的对象,弱引用关联的对象只能生存到下一次垃圾回收之前
4)虚引用:也叫幽灵引用或者幻影引用,它是最弱的一种引用,虚引用不会引用一个对象的生命周期,也无法通过一个虚引用获取一个对象实例,只是虚引用的对象被回收时会有一个通知返回回去

两次标记——死刑

  1. 一个对象在进行根搜索后发现没有与 GC Roots 相关联的引用链(和皇帝没有关系),那么它将被第一次标记并且进行一次判断,判断该对象是否覆盖了 finalize 方法(被下了死刑),如果是的,则认为有必要执行回收(死刑),如果不是则判断 finalize 方法是否已经被虚拟机调用过,如果已经调用过了,则认为没必要执行了(因为已经执行过死刑了)
  2. 如果一个对象被判定为执行死刑,那么这个对象将会被放置在一个名为 F-Queue 的队列中(关起来了),这个队列会在另外一条线程中执行死刑,因为队列中的对象可能存在死循环等情况(危险分子),在 GC 主线程中执行可能导致整个 GC 崩溃
  3. 稍后 GC 便会新开一条线程来执行死刑,它先对 F-Queue 中的对象进行第二次标记,这时如果队列中有个对象与引用链上任何一个对象建立关联(有人给你喊刀下留人),那么在这次标记中它将会被移出 F-Queue,不然就死了

永久代就不会被杀吗

JVM 规范中说过方法区(永久代)可以不实现垃圾回收,但是被上了免死金牌的永久代也是可以杀的,只是杀的少些而已,不像新生代,一次垃圾收集就可以杀掉 70%~95% 的对象
1. 永久代回收只要针对两部分内容:废弃常量和无用的类
1)回收废弃常量例子:一个字符串“abc”已经进入了常量池中,但是当前系统没有任何一个 String 对象叫做“abc”,而且如果必要的话(没内存啦),那么这个对象将会被请出常量池(朝廷没钱了,就不给一些朝中无人的王爷发钱了,自己过日子去)
2)判断一个类似“无用的类”
·该类所有的实例都被杀掉
·加载该类的 ClassLoader 已经被杀掉
·该类的 Class 对象没有在任何地方被引用,没有在任何地方通过反射访问该类地方法
满足这三个条件也并不是一定要杀掉,详见类卸载,主要在经常要大量使用反射、CGLib、动态代理、动态生成 JSP、OSGI 等场景需要配置下,以保证永久代不会溢出

一个例子

问题:下面代码中,第几行的哪个对象符合垃圾回收标准?

1 Object a = new Object(); 
2 Object b = new Object(); 
3 Object c = new Object(); 
4 a = b; 
5 a = c; 
6 c = null; 
7 a = null;

答案:直到第 7 行时才有一个对象 c 符合了垃圾回收标准

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3190 引用 • 8214 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...