finalize()方法和finalization

首先finalize和finalization作为函数,属于析构函数,那么什么是析构函数呢?

析构函数:是一个对象被撤销时自动调用的,析构与构造函数相反,当对象所在的函数一调用完毕,系统自动执行析构函数,往往用来做"清理善后"的工作

finalize()方法

java提供finalize()方法,当垃圾回收器准备释放内存的时候,会先调用finalize()方法

垃圾回收器(garbage collector)决定回收某对象时,就会运行该对象的finalize()方法;

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只保证会尽最大的努力执行,但是具体什么时候执行以及会不会执行都是未知的。

finalization的目的:

GC本来就是内存回收了,应用还需要在finalization做什么呢?

答案是大部分时候,什么都不用做(也就是不需要重载)。只有在某些很特殊的情况下,比如你调用了一些native的方法(一般是C写的),可以要在finaliztion里去调用C的释放函数。 

finalization是对象逃脱死亡的最后一次机会。(只要重新与引用链上的任何一个对象建立关联即可。)但是不建议使用,运行代价高昂,不确定性大,且无法保证各个对象的调用顺序。可用try-finally或其他替代。

finalize()方法的缺点:

  1. 可能是使对象复活
  2. finalize()执行的时间是不固定的,由GC决定,极端情况下,没有GC就不会执行finalize()方法
  3. 一个糟糕的finalize()会影响GC的性能

猜你喜欢

转载自blog.csdn.net/weixin_43224539/article/details/91369320
今日推荐