zoukankan      html  css  js  c++  java
  • 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可以做的更好,

    心有多大,天有多高,一起奋斗!!
  • 相关阅读:
    echarts折线图
    利用echarts制作词云
    本周总结
    本周总结
    云服务器项目数据库连接超时问题解决
    iOS下载图片失败
    解决后台json数据返回的字段需要替换的问题
    设置User Agent
    Xcode升级到9.3之后pod问题
    gitLab创建自己的私有库
  • 原文地址:https://www.cnblogs.com/zhaolei1996/p/10629628.html
Copyright © 2011-2022 走看看