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可以做的更好,

    心有多大,天有多高,一起奋斗!!
  • 相关阅读:
    Balance的数学思想构造辅助函数
    1663. Smallest String With A Given Numeric Value (M)
    1680. Concatenation of Consecutive Binary Numbers (M)
    1631. Path With Minimum Effort (M)
    1437. Check If All 1's Are at Least Length K Places Away (E)
    1329. Sort the Matrix Diagonally (M)
    1657. Determine if Two Strings Are Close (M)
    1673. Find the Most Competitive Subsequence (M)
    1641. Count Sorted Vowel Strings (M)
    1679. Max Number of K-Sum Pairs (M)
  • 原文地址:https://www.cnblogs.com/zhaolei1996/p/10629628.html
Copyright © 2011-2022 走看看