zoukankan      html  css  js  c++  java
  • JVM中对象的销毁

    1、可达性分析算法:

    可达性分析算法用来寻找将要销毁的对象,它的基本思路是:通过一系列的称为“GC ROOTs”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径成为引用链,当一个对象到GC ROOTs没有任何引用链想连时,则证明此对象是不可用的。如下图所示:

    对象 object5/object6/object7 虽然相互关联,但它们到GC Roots 是不可达的,所以它们会被判定为可回收的对象。

    在 Java 语言中,可作为GC Roots的对象包括下面几种:

      ·虚拟机栈(栈帧中的本地变量表)中引用的对象

      ·本地方法栈中 Native方法 引用的对象

      ·方法区中类静态属性引用的对象

      ·方法区中常量引用的对象

    2、宣判对象死亡的过程:

    此过程以流程图的形式表示更为直观:

    F-Queue 队列的执行,是由一个虚拟机自动建立的、低优先级的 Finalizer 线程执行的。这里的执行是指虚拟机会触发这个方法,但不保证会等待方法执行结束,这样是为了防止 Finalizer 执行缓慢或发生死循环,进而引起 F-Queue 队列中其他对象永久等待,甚至整个内存回收系统崩溃。

    下面给出一段 finalize() 被执行但对象仍然存活的示例:

    /**
     * 此代码演示了两点:
     * 1.对象可以在被GC时自我拯救
     * 2.这种自救的机会只有一次。因为一个对象的 finalize()方法最多只会被系统自动调用一次
     * @author yangtf
     *
     */
    public class FinalizeEscapeGC {
        public static FinalizeEscapeGC SAVE_HOOK = null;
        
        public void isAlive(){
            System.out.println("Yes,I am still alive");
        }
        
        @Override
        protected void finalize() throws Throwable{
            super.finalize();
            System.out.println("finalize method executed!");
            FinalizeEscapeGC.SAVE_HOOK = this;    // 将自己赋值给 SAVE_HOOK
        }
        
        public static void main(String[] args) throws InterruptedException {
            SAVE_HOOK = new FinalizeEscapeGC();
            
            // 对象第一次成功拯救自己
            SAVE_HOOK = null;
            System.gc();
            
            // finalize方法优先级很低,所以暂停0.5秒以等待它
            Thread.sleep(500);
            if (SAVE_HOOK != null) {
                SAVE_HOOK.isAlive();
            } else {
                System.out.println("No, I am dead");
            }
            
            // 下面这段代码与上面完全相同,但这次自救失败了
            SAVE_HOOK = null;
            System.gc();
            
            Thread.sleep(500);
            if (SAVE_HOOK != null) {
                SAVE_HOOK.isAlive();
            } else {
                System.out.println("No, I am dead");
            }
        }
    }

    执行结果:

    finalize method executed!
    Yes,I am still alive
    No, I am dead

    从结果可以看出,SAVE_HOOK 对象的 finalize() 方法确实被GC收集器触发过,并且在被收集前成功逃脱了。

    执行第二次失败,因为任何一个对象的 finalize() 方法都只会被系统自动调用一次,如果对象面临下一次回收,它的 finalize() 方法不会被再次执行,因此第二段代码的自救失败。

    3、对象的引用

    JDK1.2后,Java 将对象引用概念进行扩张,将其分为:强引用、软引用、弱引用、虚引用,四种引用强度依次减弱。

    1)强引用:代码中普遍存在,类似“Object obj = new Object()”。只要强引用还存在,垃圾收集器永远不会对其引用的对象进行回收。

    2)软引用:用来描述还有用,但并非必须的对象。对软引用关联的对象第一次不回收,若第一次回收之后内存仍不够,则将其回收;即进行第二次回收。

    3)弱引用:比软引用更弱的引用。第一次垃圾回收就会将其回收。

    4)虚引用:也称为幽灵引用或幻影引用。一个对象是否有虚引用存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用的唯一目的,就是能在这个对象被收集器回收时收到一个系统通知。

  • 相关阅读:
    yii 引入文件
    CodeForces 621C Wet Shark and Flowers
    面试题题解
    POJ 2251 Dungeon Master
    HDU 5935 Car(模拟)
    HDU 5938 Four Operations(暴力枚举)
    CodeForces 722C Destroying Array(并查集)
    HDU 5547 Sudoku(dfs)
    HDU 5583 Kingdom of Black and White(模拟)
    HDU 5512 Pagodas(等差数列)
  • 原文地址:https://www.cnblogs.com/tf-Y/p/5272781.html
Copyright © 2011-2022 走看看