zoukankan      html  css  js  c++  java
  • 垃圾收集之对象的标记

    在可达性分析算法中不可达的对象,并没有立即被回收。对象被判断为“死亡”时,至少需要经历两次标记过程:

    1.如果对象在进行可达性分析后发现没有与GC Roots相连接的引用链,会被第一次标记并且进行一次筛选,筛选的条件时此对象是否有必要执行finalize()方法。当对象没有覆盖finalize()方法或者fianalize()方法已经被虚拟机调用过,虚拟机将这两种情况视为“没有必要执行”。这个机制说明,如果某个对象中有重载的fianlize()方法,这个方法只能被执行一次。

    2.当进行了第一次标记并且判定此对象有必要执行finalize()方法时,这个对象会被放置在F-Queue的队列中,虚拟机会自动创建一个低优先级的Finalizer线程,由此线程来“执行”对象的finalize()方法。

    但是此处的执行并不是平常意义的执行,它会出发此方法,但是并不承若会等待它运行结束。这样考虑的原因是如果此方法中存在死循环或者执行缓慢时,F-Queue队列中其它对象永久处于等待,甚至会造成内存回收系统的崩溃。

    3.在这之后,GC将对F-Queue队列中的对象进行第二次小规模标记,如果对象在finalize()中重新与引用链上的任何一个对象建立了关联,那么在第二次标记时它将被移除出“即将回收”的集合,否则,对象就基本上被判定为可回收。

    总的来说,java中判定一个对象是否回收需要进行两次标记,在发现没有与GC Roots相关联时,会被第一次标记。并且进行一次筛选,这次的筛选结果会成为第二次标记的重要依据。筛选条件为是否有必要执行finalize()方法。没有重写finalize()方法或者finalize方法已经被调用过判定为“没有必要执行”。被判断为“有必要执行”的对象会进入F-Queue队列中,由java虚拟机自动建立的、低优先级的Finalize线程进行没有保证的执行,即调用对象的finalize()方法但是并不会承诺会等待它运行结束。GC会对F-Queue中的对象进行第二次小规模标记,如果对象在finalize()方法中重新建立起和GC Roots的关联,则第二次标记会将此对象移除出“即将回收”的集合。

  • 相关阅读:
    20175322 周弋鸿 2018-2019-2 《Java程序设计》第八周学习总结
    2018-2019-2-20175303 实验二 《Java开发环境的熟悉》实验报告
    20175322 《Java程序设计》第七周学习总结
    20175322 《Java程序设计》第六周学习总结
    2018-2019-2 20175322实验一《Java开发环境的熟悉》实验报告
    20175322《Java程序设计》第五周学习总结
    《Java程序设计》第四周学习总结
    《Java程序设计》第三周学习总结
    《Java程序设计》第二周学习总结
    第一周学习总结
  • 原文地址:https://www.cnblogs.com/xuhan74520/p/13595666.html
Copyright © 2011-2022 走看看