POST
Java 的 finalize() 方法总结
Java 提供的finalize()
方法是定义 JObject 类中的方法。作用是帮助我们进行资源释放,类似于 C++ 中的析构函数。但是需要注意的是该方法根本上和 C++ 中的析构函数是不同的。
我们都知道 Java 是运行在 JVM 上的,JVM 的垃圾回收机制承担了系统资源释放的任务,因此在编写Java 程序的时候是不用考虑显式的调用方法进行资源释放的。这是因为 Java 是完全面向对象的语言,所有对象都驻留在堆内存,因此局部对象就不存在。而与 Java 不同,C++ 支持局部对象(基于栈)和全局对象(基于堆)。因此在 C++ 语言中引入了析构函数用来处理资源的释放。析构函数的执行时机是确定的,在对象的作用域结束或者显式调用的时候会被执行。一般在 C++ 编程中,子类的析构函数都会重写父类的析构函数用于本类的资源的释放。
而 Java 的finalize()
方法则不同,finalize()虽然也会被用来进行资源的释放,但是 finalize() 方法的执行时机确是不确定的。原因是因为finalize()
是在垃圾回收时被调用的,而何时进行垃圾回收是由JVM 根据当前的资源状况来决定,因此这个时间是无法保证的。
通常 JVM 会对当前的内存状况进行评估,只有当资源快耗尽或者有进程因为资源不足退出和排队等待的时候,JVM 会进行垃圾的回收。这个时候finalize()
会被执行。因此如果我们想在确定的时间点用finalize()
来释放有关的资源是十分不可靠的。
有意思的一点,Java 的垃圾回收机制虽然简化了编程,程序员无需考虑资源的释放导致的内容泄漏问题,但是却无法知道申请的对象何时被系统撤销,即使该对象的作用域是可以预知的(不再被运行状态引用或间接地通过其他对象引用时)。
当然,Java 也提供了System.gc()
方法,System.gc()
会强制要求系统进行垃圾回收,从而可以增加finalize()
的调用几率,缺点是强制进行垃圾回收会影响系统的性能。
下面对finalize()
方法来做一个总结:
finalize()
方法可以被用来进行系统资源的释放;- 系统在进行垃圾回收,准备释放对象所占用的内存空间之前会调用对象的
finalize()
方法; - 因为系统进行垃圾回收的时机不确定,所以
finalize()
的执行时间是不确定的; finalize()
只会在对象内存回收前被调用一次。