finalize()来自Object的protected 方法,同clone()需要用户具体实现.
一、源码中的介绍
1、    Called by the garbage collector on an object when garbage collection determines that there are no more references to the object.
    当垃圾回收器发现一个对象实例没有任何的引用与之关联,在准备执行垃圾回收之前该方法才会被调用。
    A subclass overrides the finalize method to dispose of system resources or to perform other cleanup.
    子类重写该方法实现对系统资源的清理工作,例如对象实例废弃之前,结束I/O操作,断开数据库连接。
    该方法需要实现者自己书写处理代码。
2、
     The Java programming language does not guarantee which thread will invoke the  finalize method for any given object. It is
     * guaranteed, however, that the thread that invokes finalize will not be holding any user-visible synchronization locks when finalize is
     * invoked. If an uncaught exception is thrown by the finalize method, the exception is ignored and finalization of that object terminates.
    Java语言不能保证哪一个线程调用给定对象实例的finalize(),但是保证的是调用该方法的线程不再持有用户可见的同步锁。
    如果该方法抛出的异常没有被捕获,那么异常将会被忽略、finalize()被终止。
3、
    After the {@code finalize} method has been invoked for an object, no further action is taken until the Java virtual machine has again
     * determined that there is no longer any means by which this object can be accessed by any thread that has not yet died, including possible
     * actions by other objects or classes which are ready to be finalized, at which point the object may be discarded.
    调用了finalize()之后,不会采取任何的动作(包括那些已经finalized的对象的动作),直到JVM再次检测到该对象已经不被任何线程使用,这个时候该对    象就要被丢弃了。
    [使用finalize()的对象,可以逃避一次被垃圾回收器回收,在下次gc的时候,势必会将其清理。]

4、    一般情况下,java的垃圾是不需要程序员来处理的,但是一些non-java程序(C,C++)的Native方法产生的内存垃圾需要这种方法来处理。所以该方法还是要慎重使用的。

二、详细介绍

  1 、java的GC只负责内存相关的清理,所有其它资源的清理必须由程序员手工完成。要不然会引起资源泄露,有可能导致程序崩溃。
  2 、调用GC并不保证GC实际执行。

  3 、finalize抛出的未捕获异常只会导致该对象的finalize执行退出。

  4 、用户可以自己调用对象的finalize方法,但是这种调用是正常的方法调用,和对象的销毁过程无关。

  5、 JVM保证在一个对象所占用的内存被回收之前,如果它实现了finalize方法,则该方法一定会被调用。Object的默认finalize什么都不做,为了效率,GC可以认为一个什么都不做的finalize不存在。

  6 、对象的finalize调用链和clone调用链一样,必须手工构造。

三、对象的销毁过程[转]

  在对象的销毁过程中,按照对象的finalize的执行情况,可以分为以下几种,系统会记录对象的对应状态:
  unfinalized 没有执行finalize,系统也不准备执行。

  finalizable 可以执行finalize了,系统会在随后的某个时间执行finalize。

  finalized 该对象的finalize已经被执行了。

  GC怎么来保持对finalizable的对象的追踪呢。GC有一个Queue,叫做F-Queue,所有对象在变为finalizable的时候会加入到该Queue,然后等待GC执行它的finalize方法。

  这时我们引入了对对象的另外一种记录分类,系统可以检查到一个对象属于哪一种。

  reachable 从活动的对象引用链可以到达的对象。包括所有线程当前栈的局部变量,所有的静态变量等等。

  finalizer-reachable 除了reachable外,从F-Queue可以通过引用到达的对象

  unreachable 其它的对象。

状态转换图

  1 首先,所有的对象都是从Reachable+Unfinalized走向死亡之路的。

  2 当从当前活动集到对象不可达时,对象可以从Reachable状态变到F-Reachable或者Unreachable状态。

  3 当对象为非Reachable+Unfinalized时,GC会把它移入F-Queue,状态变为F-Reachable+Finalizable。

  4
好了,关键的来了,任何时候,GC都可以从F-Queue中拿到一个Finalizable的对象,标记它为Finalized,然后执行它的
finalize方法,如果该对象在这个方法中又可达了,于是该对象变成Reachable了(并且Finalized)。而finalize方法执行
时,又有可能把其它的F-Reachable的对象变为一个Reachable的,这个叫做对象再生。

  5
当一个对象在Unreachable+Unfinalized时,如果该对象使用的是默认的Object的finalize,或者虽然重写了,但是新的实
现什么也不干。为了性能,GC可以把该对象之间变到Reclaimed状态直接销毁,而不用加入到F-Queue等待GC做进一步处理。

  6 从状态图看出,不管怎么折腾,任意一个对象的finalize只至多执行一次,一旦对象变为Finalized,就怎么也不会在回到F-Queue去了。当然没有机会再执行finalize了。

  7 当对象处于Unreachable+Finalized时,该对象离真正的死亡不远了。GC可以安全的回收该对象的内存了。进入Reclaimed。

 四、何时使用finalize()
  
1 最重要的,尽量不要用finalize,太复杂了,还是让系统照管比较好。可以定义其它的方法来释放非内存资源(如上解释)。

  2 如果用,尽量简单。

  3 如果用,避免对象再生,这个是自己给自己找麻烦。

  4 可以用来保护非内存资源被释放。即使我们定义了其它的方法来释放非内存资源,但是其它人未必会调用该方法来释放。在finalize里面可以检查一下,如果没有释放就释放好了,晚释放总比不释放好。

  5 即使对象的finalize已经运行了,不能保证该对象被销毁。要实现一些保证对象彻底被销毁时的动作,只能依赖于java.lang.ref里面的类和GC交互了

java-finalize的更多相关文章

  1. 【学习笔记】Java finalize()的使用

    <Java编程思想>中有提到,Java的垃圾回收器并不是那么靠谱,垃圾回收会占用很大的资源开销,垃圾回收器很懒,当变量和对象不再被引用.脱离作用域的时候,垃圾回收器会不定时的进行垃圾回收, ...

  2. Java finalize方法使用

    <JAVA编程思想>: Java提供finalize()方法,垃圾回收器准备释放内存的时候,会先调用finalize(). (1).对象不一定会被回收. (2).垃圾回收不是析构函数. ( ...

  3. java finalize方法总结、GC执行finalize的过程

    注:本文的目的并不是鼓励使用finalize方法,而是大致理清其作用.问题以及GC执行finalize的过程. 1. finalize的作用 finalize()是Object的protected方法 ...

  4. Java finalize以及Garbage Collection

    Java的垃圾回收机制: Java的垃圾回收并不等于C++中的析构.Java中,只有在程序濒临存储空间用完的那一刻,对象占用的空间才会释放.所以,在JAVA程序中,我们通常只考虑创建对象,而从不关心对 ...

  5. java finalize学习

    1 finalize()调用的时机 与C++的析构函数(对象在清除之前析构函数会被调用)不同,在Java中,由于GC的自动回收机制,因而并不能保证finalize方法会被及时地执行(垃圾对象的回收时机 ...

  6. 【Java面试题系列】:Java中final finally finalize的区别

    本篇为[Java面试题系列]第三篇,文中如有错误,欢迎指正. 第一篇链接:[Java面试题系列]:Java基础知识常见面试题汇总 第一篇 第二篇链接:[Java面试题系列]:Java基础知识常见面试题 ...

  7. Java 异常基础详解

    目录 1. Java 中的异常 1.1 什么是异常? 1.2 什么是异常处理? 1.2.1 异常处理的优势 1.3 Java 异常类的层次结构 1.4 异常类型 1.5 检查和未检查异常之间的区别 1 ...

  8. 深入了解Java虚拟机和内存管理

    1.java程序的执行过程      java源文件->解析器->class文件->java类加载器->java运行时数据区->执行引擎 2.我们接下来看一下java运行 ...

  9. C++ Style Languages: C++, Objective-C, Java, C#

    Hyperpolyglot.org From Hyperpolyglot.org C++ Style Languages: C++, Objective-C, Java, C# a side-by-s ...

  10. java---final、finally、finalize的区别

    Java finalize方法使用 标签: javaappletobjectwizardjvm工作 2011-08-21 11:37 48403人阅读 评论(5) 收藏 举报  分类: Java(96 ...

随机推荐

  1. freebsd

    #cd /usr/ports/devel/binutils && make install

  2. 为什么Lisp没有流行起来

    很久以前,这种语言站在计算机科学研究的前沿,特别是人工智能的研究方面.现在,它很少被用到,这一切并不是因为古老,类似古老的语言却被广泛应用.其他类似的古老的语言有??FORTRAN. COBOL. L ...

  3. ID卡

    ID卡全称为身份识别卡(Identification Card),是一种不可写入的感应卡,含固定的编号,主要有台湾SYRIS的EM格式.美国HIDMOTOROLA等各类ID卡.ID卡与磁卡一样,都仅仅 ...

  4. SQL实现递归及存储过程中 In() 参数传递解决方案

    1.SQL递归 在SQL Server中,我们可以利用表表达式来实现递归算法,一般用于阻止机构的加载及相关性处理. -->实现: 假设OrganiseUnit(组织机构表)中主要的三个字段为Or ...

  5. delphi webbrowser 经常用法演示样例

    var Form : IHTMLFormElement ; D:IHTMLDocument2 ; begin with WebBrowser1 do begin D := Document as IH ...

  6. Ext JS学习第六天 Ext自定义类(一)

    此文来记录学习笔记 •我们在之前的学习,已经对ExtJS有了一个初步的认识,那么如果要学好ExtJS,对于javascript是必须的,也就是说,对于理解ExtJS底层基础架构的理解也是必须的.那么我 ...

  7. 几种经典排序算法的JS实现

    一.冒泡排序 function BubbleSort(array) { var length = array.length; for (var i = length - 1; i > 0; i- ...

  8. Reverse Integer - Palindrome Number - 简单模拟

    第一个题目是将整数进行反转,这个题实现反转并不难,主要关键点在于如何进行溢出判断.溢出判断再上一篇字符串转整数中已有介绍,本题采用其中的第三种方法,将数字转为字符串,使用字符串比较大小的方法进行比较. ...

  9. 「C」 函数、运算、流程控制

    一.函数 (一)什么是函数 任何一个C语言程序都是由一个或者多个程序段(小程序)构成的,每个程序段都有自己的功能,我们一般称这些程序段为“函数”. (二)函数的定义 目的:将一个常用的功能封装起来,方 ...

  10. [C++参考]私有成员变量的理解

    私有成员变量的概念,在脑海中的现象是,以private关键字声明,是类的实现部分,不对外公开,不能在对象外部访问对象的私有成员变量. 然而,在实现拷贝构造函数和赋值符函数时,在函数里利用对象直接访问了 ...