对象是否存活

时间:2022-12-27 18:22:02

(1)引用计数算法给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值加1;当引用失效时,计数器减1;任何时刻计数器都为0的对象就是不可能再被使用的。实现简单,判断效率高,Java没有选用主要因为它很难解决对象相互循环引用的问题。

Java采用的方式:

1)可达性分析:"GC Roots"的对象作为起始点,从这些节点开始向下搜索,当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的,下图对象object5, object6, object7虽然有互相判断,但它们到GC Roots是不可达的,所以它们将会判定为是可回收对象。Java通过有向图来记录和管理堆内存中的所有对象。

对象是否存活

可作为GC Roots对象的包括如下几种:
    a.虚拟机栈(栈桢中的本地变量表)中的引用的对象
    b.方法区中的类静态属性引用的对象和常量
    d.本地方法栈JNI的引用的对象 

2finalize()方法最终判定对象是否存活

不可达的对象并非是非死不可的,不可达的对象要经历两次标记筛选。

1).第一次标记筛选:此对象是否有必要执行finalize()方法。
    当对象没有覆盖finalize方法,或者finzlize方法已经被虚拟机调用过,虚拟机将这两种情况都视为没有必要执行,对象被回收。
  2).第二次标记:低优先级的finalize线程
    有必要执行finalize方法的对象将会被放置在F-Queue的队列之中,并在稍后由一条虚拟机自动建立的、低优先级Finalizer线程去执行。这里所谓的执行是指虚拟机会触发这个方法,但并不承诺会等待它运行结束。这样做的原因是,如果一个对象finalize()方法中执行缓慢,或者发生死循环,将很可能会导致F-Queue队列中的其他对象永久处于等待状态,甚至导致整个内存回收系统崩溃。
    Finalize()方法只要重新与引用链上的任何的一个对象建立关联即可,譬如把自己this赋值给某个类变量或对象的成员变量,那么就逃离死亡

 对象是否存活


2、回收方法区:

新生代一次垃圾收集一般回收75~95%的空间,而永久代(方法区)比较低。永久代的回收主要分为:废弃常量和无用的类。

废弃常量:常量池中有字符串“abc,但是当前系统没有任何地方引用该常量的

无用的类同时满足:该类的所有实例被回收,加载该类的classLoader被回收,Java.lang.class在任何地方没有再引用。