• finalize()及垃圾回收


    整体认识

    finalize()方法是一个与垃圾回收相关的方法(和C++中的析构函数有很大的区别),

    finalize()方法不是用于垃圾回收,而是与垃圾回收相关

    是Objecte类中的方法

    finalize()方法的说明方式 : protected void finalize()throws Throwable

    一个对象只能调用一次finalize()方法

    深入认识finalize()

    想要深入了解finalize()方法就要先对Jvm的堆内存的垃圾回收机制有一个认识;

    JVM采用垃圾回收算法是可达性分析算法,下面先了解一下可达性算法:

    可达性算法可用用下面的一个树形图来认识,若内存与GC root有连接则该内存是不可被回收的,若相应的内存与GC root没有连接的通路那么该内存就是可回收的(但不一定被回收)

    a  b  c 与GC root有连接的通路,所以他们三个都是不可回收的,而d e与GC Roots没有通路相连,所以他们是可被回收的,当然GC Roots的选取是有要求的

    可作为GC Roots的对象:

    1、 虚拟机栈(java 方法)中引用的对象

    2、 方法区中静态属性引用的对象

    3、 方法区中常量引用的对象

    4、 native方法(本地方法栈)中引用的对象

    上面我们说到若没有与GC Roots相连的对象是可回收的,但是并不是就一定可以被回收,java中对象要被回收至少要经历两次标记过程:

    第一次标记:若对象没有与GC Roots相连接则被第一次标记

    第二次标记:这次标记需要分情况讨论

            第一种情况:若该对象的类覆盖了finalize()方法,并且该对象没有调用过finalize()方法,则虚拟机将会把该对象存入到一个叫做F-Queue队列中,等到一定的时间虚拟机将会自己创建一个低优先级的线程(Finalizer),由该线程去触发finalize()方法,若finalize()方法中将此对象与还在与GC Roots相连的对象相关联,那么该对象就不会被回收,否则该对象就会被回收

            第二种情况:finalize()方法已经被调用,或者没有覆盖finalize()方法。这种情况就不会将对象放进F-Queue队列,也不会调用finalize()方法,而是对对象进行第二次标记,回收对象

    总结

    通过上面的描述知道一个与GC Roots没有连接通道的对象要想不被回收就只有在finalize()方法中将该对象与GC Roots建立联系,仿佛并不是垃圾回收而是自救的一个通道,所以finalize()方法不是用于垃圾回收,而是与垃圾回收相关,除了上述作用外,还有一个作用

    当该对象不进行自救时,在finalize()方法中执行该对象必须要执行的代码(因为该对象马上就要被回收),例如释放资源,这与try finally中finally的作用是一样的,并且finally可以做的更好,

    心有多大,天有多高,一起奋斗!!
  • 相关阅读:
    js与jquery实时监听输入框值的oninput与onpropertychange方法
    jQuery实现的浮动层div浏览器居中显示效果
    jquery代码规范让代码越来越好看
    asp.net截屏功能实现截取web页面
    拦截asp.net输出流并进行处理的方法
    asp.net调用系统设置字体文本框的方法
    asp.net网站防恶意刷新的Cookies与Session解决方法
    Attribute在.net编程中的应用(一)
    java学习——构造类之3!+5!=126
    java学习——构造类
  • 原文地址:https://www.cnblogs.com/zhaolei1996/p/10629628.html
Copyright © 2020-2023  润新知