我发现多个帖子说明不应该使用finalize()并且一般不应该使用它,因为没有人保证在应用程序的生命周期内对象将被垃圾收集(除非你实际上在应用程序的整个生命周期中都需要该对象,这是我书中的内存泄漏)。但是,让我们说我有一个Java类,它通过JNI在本地空间初始化某些内容(进行内存分配和初始化)。就我而言,有两种方法可以实现这一点:
1.在类中实现init()和deinit()方法以执行本机初始化和取消初始化。这有一个缺点,我必须处理对象的生命周期,并且不能将它留给垃圾收集器(它不像Java那样)。
2.在构造函数中进行初始化并在finalize()方法中进行取消初始化。这基本上使对象能够像任何其他Java类一样自动进行垃圾回收。
我要问的是 - 我有理由不去参加第二名吗?
谢谢,
雷纳德
答案 0 :(得分:2)
我要问的是 - 我有理由不去参加第二名吗?
原因之一是,在GC回收了finalize
方法将回收它的Java对象之前,本机资源将不会发布。
这个原因是否真正相关取决于本机资源的性质。
真的,当你想到它时,这就是Java设计师关于关闭流的争论。
他们可能没有提供close()
方法,并将其完全保留为finalize
方法...除了这会导致输出流无法很快刷新的问题,并且用尽了“文件描述符”。
他们可能完全将其留给了close()
方法...除非您忘记了close()
文件(并且没有finalize
方法)你会永久泄漏文件描述符。
相反,他们同时实施了close()
和finalize
,他们实施了后者来调用前者。因此,当程序这样说时,你可以获得关闭的优势,如果忽略调用close()
,你可以清理 1 。
1 - 当然,如果您依赖流finalize
方法进行清理,可能会出现问题;例如如果流意外仍然可以访问,或者它没有很快收集到垃圾,那么无论如何你都会用完文件描述符。并且非确定性的刷新输出也可能是一个问题。
行。当有问题的资源纯粹是内存时呢?那不是垃圾收集那么吗?
我没有看到。真正的垃圾收集不依赖于您实现finalize方法,close方法或其他明确释放内容的东西。
答案 1 :(得分:0)
当后者应该被释放时,代码执行不一定释放资源。因此,一旦您知道如果这些资源很重要,就不再需要资源,我会立即使用finalize。如果资源很小,请不要使用finalize,因为它会带来开销。