判断对象生与死

前言

《JVM中哪些内存需要回收》说了主流的垃圾收集器都是用引用计数算法和可达性分析算法来判断对象是否垃圾对象的,并且介绍了这两种算法的思想。这篇文章会对判断垃圾对象的引用和回收做进一步的展开。

1 引用

无论是引用计数算法,还是可达性分析算法均和引用脱不开关系。在 JDK 1.2 版本之后引用分为:强引用(Strongly Reference)、软引用(Soft Reference)、弱引用(Weak Reference)和虚引用(Phantom Reference)。这 4 种引用强度依次减弱。

强引用
强引用是指类似 Object obj = new Object() 这种引用关系。无论什么时候,只要强引用关系还在,那么对象就不会被回收。

软引用
软引用是用来描述一些还有用但是非必须的对象引用关系。只有软引用关系的对象,在系统将要发生内存溢出异常前会把这些对象列入可回收范围。只有垃圾收集器进行第二次回收还得不到足够的内存才会抛出内存溢出异常。在 JDK 1.2 版本之后提供了 SoftReference 类来实现软引用。

弱引用
弱引用也是用来描述那些非必须的对象的,但是它的强度比软引用更弱。当垃圾收集器发生垃圾收集时,无论内存是否足够,被弱引用的对象都会被回收。在 JDK 1.2 版本之后提供了 WeakReference 类来实现弱引用。

虚引用
这是最弱的引用关系,这个引用关系存在的唯一意义就是当虚引用对象被回收时会收到一个系统通知。在 JDK 1.2 版本之后提供了 PhantomReference 类来实现虚引用。

2 finalize()

不建议使用该方法,知道有这么一个东西就好了

即使被引用算法判断为没有被引用的对象也不是立马回收的,垃圾对象一般要经历两个阶段才会被回收:
1. 标记
被判断没有与 GC Roots 相连接的引用链的对象会被标记。
2. 筛选
等扫描标记工作完成后,就会进行一次筛选,看下被标记的对象是否有必要执行 finalize() 方法。如果对象没有覆盖 finalize() 方法,或者 finalize() 方法已经被虚拟机调用过了,那么这两种情况都会被视为“没有必要执行”。

需要执行 finalize() 方法的对象会放入一个特定的队列(F-Queue)中,由虚拟机自动建立的,低调度优先级的 Finalizer 线程去执行它们的 finalize() 方法。如果对象在 finalize() 方法也没能成功拯救自己,那么只能被回收了;如果可以成功与引用链上任何一个对象建立关系,那么就能逃过一次回收。

需要注意的是:虚拟机会触发这个方法开始执行,但是不承诺一定会等待 finalize() 方法运行结束。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容