首页 > 试题广场 >

finalize()方法什么时候被调用?析构函数(final

[问答题]
finalize()方法什么时候被调用?析构函数(finalization)的目的是什么?
参考:《深入理解Java虚拟机》
对于Java而言:
调用时机:当垃圾回收器要宣告一个对象死亡时,至少要经过两次标记过程:如果对象在进行可达性分析后发现没有和GC Roots相连接的引用链,就会被第一次标记,并且判断是否执行finalizer( )方法,如果对象覆盖finalizer( )方法且未被虚拟机调用过,那么这个对象会被放置在F-Queue队列中,并在稍后由一个虚拟机自动建立的低优先级的Finalizer线程区执行触发finalizer( )方法,但不承诺等待其运行结束。
finalization的目的:对象逃脱死亡的最后一次机会。(只要重新与引用链上的任何一个对象建立关联即可。)但是不建议使用,运行代价高昂,不确定性大,且无法保证各个对象的调用顺序。可用try-finally或其他替代。
发表于 2017-08-15 21:23:50 回复(9)

1)垃圾回收器(garbage collector)决定回收某对象时,就会运行该对象的finalize()方法; 2)GC本来就是内存回收了,应用还需要在finalization做什么呢? 答案是大部分时候,什么都不用做(也就是不需要重载)。只有在某些很特殊的情况下,比如你调用了一些native的方法(一般是C写的),可以要在finaliztion里去调用C的释放函数。

编辑于 2018-06-11 18:25:21 回复(0)
  finalize()是Object的protected方法,子类可以覆盖该方法以实现资源清理工作,GC在回收对象之前调用该方法。
当对象变成(GC Roots)不可达时,GC会判断该对象是否覆盖了finalize方法,若未覆盖,则直接将其回收。否则,若对象未执行过finalize方法,将其放入F-Queue队列,由一低优先级线程执行该队列中对象的finalize方法。执行finalize方法完毕后,GC会再次判断该对象是否可达,若不可达,则进行回收,否则,对象“复活”。
发表于 2019-03-03 20:13:20 回复(1)
1.在释放对象占用的内存之前,垃圾收集器会调用对象的finalize()方法。
2.析构finalization,比如你在调用了一些native的方法,可以要在finaliztion里去调用释放函数
发表于 2016-05-11 16:57:54 回复(0)
finalize()方法也叫收尾方法。
一旦垃圾回收器准备好释放对象占用的存储空间,首先会去调用finalize()方法①进行一些必要的清理工作(对垃圾回收器不能处理的特殊情况进行处理)(例子在下边)②也有可能使该对象重新被引用,我习惯叫这种作用为复活。注意!!每个对象的finalize()方法只能被执行一次,第二次就会直接跳过finalize()方法,这就是为了防止出现对象无限复活,内存空间只增不减。

一般忽略第二种情况,概念就变成了:一旦垃圾收集器准备好释放对象占用的存储空间(进入第一个回收周期),首先会去调用finalize()方法进行一些必要的清理工作,只有到下一次再进行垃圾回收动作(下一个回收周期)的时候,才会真正释放这个对象所占用的内存空间。

例子:1)由于在分配内存的时候可能采用了类似 C语言的做法,而非JAVA的通常new做法。这种情况主要发生在native method中,比如native method调用了C/C++方法malloc()函数系列来分配存储空间,但是除非调用free()函数,否则这些内存空间将不会得到释放,那么这个时候就可能造成内存泄漏。但是由于free()方法是在C/C++中的函数,所以finalize()中可以用本地方法来调用它。以释放这些“特殊”的内存空间。2)又或者打开的文件资源,这些资源不属于垃圾回收器的回收范围。

System.runFinalization()和System.gc()是做什么的呢? 我个人的理解,这两个函数分别是应用层向JVM发出一个信号,告诉JVM,希望你能尽快的回收内存和调用对象的finaliztion方法,但是只是一个请求,而JVM只保证会尽最大的努力执行,但是具体什么时候执行以及会不会执行都是未知的。



编辑于 2018-05-27 23:04:06 回复(0)
finalize是Object类的一个方法,该方法在Object类中的声明
                protected void finalize() throws Throwable { }
    在垃圾回收器执行时会调用被回收对象的finalize()方法,可以覆盖此方法来实现对其资源的回收。注意:一旦垃圾回收器准备释放对象占用的内存,将首先调用该对象的finalize()方法,并且下一次垃圾回收动作发生时,才真正回收对象占用的内存空间。
发表于 2017-01-06 22:09:02 回复(0)
在释放对象占用的内存之前,垃圾收集器会调用对象的finalize()方法。一般建议在该方法中释放对象持有的资源。
发表于 2015-10-29 12:10:42 回复(2)
垃圾回收器(garbage colector)决定回收某对象时,就会运行该对象的finalize()方法,但是在java中很不幸,如果内存总是充足的,那么垃圾回收啃呢个永远不会进行,也就是finailize()可能永远不被执行,显然指望它作收尾工作时靠不住的。那么finalize()究竟是做什么的呢?它最主要的用途是回收特殊渠道申请的内存。java程序由垃圾回收器,所以一般情况下内存问题不用程序由操心。但有一种JNI(java native interface)调用non-java程序(c或c++),finalize()的工作就是回收这部分内存。
发表于 2016-03-23 22:23:19 回复(1)
主要的用途是回收特殊渠道申请的内存。Java程序有垃圾回收器,所以一般情况下内存问题不用程序员操心。但有一种JNI(Java Native Interface)调用non-Java程序(C或C++),finalize()的工作就是回收这部分的内存。
发表于 2017-03-27 15:45:40 回复(0)
finalize是object 类的一个方法,在垃圾回收期执行时会调用被回收对象的finalize方法,可以覆盖此方法来实现对其他资源的回收,例如关闭文件等,需要注意的是,一旦垃圾回收期准备好释放对象占用的内存空间,将首先调用其finalize方法,并且在下一次垃圾回收动作发生时才会真正回收对象占用的内存
发表于 2016-03-28 14:40:41 回复(1)
finalize()方法也叫收尾方法。 一旦垃圾回收器准备好释放对象占用的存储空间,首先会去调用finalize()方法①进行一些必要的清理工作(对垃圾回收器不能处理的特殊情况进行处理)(例子在下边)②也有可能使该对象重新被引用,我习惯叫这种作用为复活。注意!!每个对象的finalize()方法只能被执行一次,第二次就会直接跳过finalize()方法,这就是为了防止出现对象无限复活,内存空间只增不减。 一般忽略第二种情况,概念就变成了:一旦垃圾收集器准备好释放对象占用的存储空间(进入第一个回收周期),首先会去调用finalize()方法进行一些必要的清理工作,只有到下一次再进行垃圾回收动作(下一个回收周期)的时候,才会真正释放这个对象所占用的内存空间。 例子:1)由于在分配内存的时候可能采用了类似 C语言的做法,而非JAVA的通常new做法。这种情况主要发生在native method中,比如native method调用了C/C++方法malloc()函数系列来分配存储空间,但是除非调用free()函数,否则这些内存空间将不会得到释放,那么这个时候就可能造成内存泄漏。但是由于free()方法是在C/C++中的函数,所以finalize()中可以用本地方法来调用它。以释放这些“特殊”的内存空间。2)又或者打开的文件资源,这些资源不属于垃圾回收器的回收范围。 System.runFinalization()和System.gc()是做什么的呢? 我个人的理解,这两个函数分别是应用层向JVM发出一个信号,告诉JVM,希望你能尽快的回收内存和调用对象的finaliztion方法,但是只是一个请求,而JVM只保证会尽最大的努力执行,但是具体什么时候执行以及会不会执行都是未知的。 详情请看我的博客https://blog.csdn.net/qq_36711757/article/details/80470820
发表于 2021-08-14 23:04:04 回复(0)
finalize是object 类的一个方法,在垃圾回收期执行时会调用被回收对象的finalize方法,可以覆盖此方法来实现对其他资源的回收,例如关闭文件等,一旦垃圾回收期准备好释放对象占用的内存空间,将首先调用其finalize方法,并且在下一次垃圾回收动作发生时才会真正回收对象占用的内存
发表于 2020-07-01 22:29:18 回复(0)
finalize()用在当垃圾回收器,因内存紧张而去回收某些对象时,这时会调用其finalize();如果内存不紧张,就不会去回收对象,那finalize()不会被调用。当考虑到JNI(java native interface),有时finalize()可以去回收这部分内存。
发表于 2020-06-06 21:29:59 回复(0)

在被垃圾回收器回收之前调用。由于特殊原因对分配的内存回收处理(如jni),一般没特殊作用。

发表于 2020-03-05 19:58:12 回复(0)
当jvm 要回收一个对象时,要调用对象的finalixed()方法,如果对象不被回收的话,finalized就永远不被执行,finlized方法主要是去释放native()方法(c语言写的)的
编辑于 2019-11-21 23:58:34 回复(0)
参考:《深入理解Java虚拟机》 对于Java而言: 调用时机:当垃圾回收器要宣告一个对象死亡时,至少要经过两次标记过程:如果对象在进行可达性分析后发现没有和GC Roots相连接的引用链,就会被第一次标记,并且判断是否执行finalizer( )方法,如果对象覆盖finalizer( )方法且未被虚拟机调用过,那么这个对象会被放置在F-Queue队列中,并在稍后由一个虚拟机自动建立的低优先级的Finalizer线程区执行触发finalizer( )方法,但不承诺等待其运行结束。 finalization的目的:对象逃脱死亡的最后一次机会。(只要重新与引用链上的任何一个对象建立关联即可。)但是不建议使用,运行代价高昂,不确定性大,且无法保证各个对象的调用顺序。可用try-finally或其他替代。
发表于 2019-10-25 17:15:02 回复(0)
大致描述一下finalize()流程:当对象变成(GC Roots)不可达时,GC会判断该对象是否覆盖了finalize方法,若未覆盖,则直接将其回收。否则,若对象未执行过finalize方法,将其放入F-Queue队列,由一低优先级线程执行该队列中对象的finalize方法。执行finalize方法完毕后,GC会再次判断该对象是否可达,若不可达,则进行回收,否则,对象“复活”。
发表于 2019-09-02 15:05:45 回复(0)
垃圾回收器(garbage collector)决定回收某对象时,就会运行该对象的finalize()方法 但是在Java中很不幸,如果内存总是充足的,那么垃圾回收可能永远不会进行,也就是说filalize()可能永远不被执行,显然指望它做收尾工作是靠不住的。 那么finalize()究竟是做什么的呢?它最主要的用途是回收特殊渠道申请的内存。Java程序有垃圾回收器,所以一般情况下内存问题不用程序员操心。但有一种JNI(Java Native Interface)调用non-Java程序(C或C++),finalize()的工作就是回收这部分的内存。
发表于 2019-04-28 16:51:40 回复(0)
垃圾回收器(garbage collector)决定回收某对象时,就会运行该对象的finalize()方法 但是在Java中很不幸,如果内存总是充足的,那么垃圾回收可能永远不会进行,也就是说filalize()可能永远不被执行,显然指望它做收尾工作是靠不住的。 那么finalize()究竟是做什么的呢?它最主要的用途是回收特殊渠道申请的内存。Java程序有垃圾回收器,所以一般情况下内存问题不用程序员操心。但有一种JNI(Java Native Interface)调用non-Java程序(C或C++),finalize()的工作就是回收这部分的内存。
发表于 2019-04-27 21:05:08 回复(0)
回收特定渠道收取的内存
发表于 2019-04-26 23:01:15 回复(0)