finalize方法中的异常

9

可能是重复问题:
finalize方法和异常

当一个对象即将从内存中释放时,垃圾回收器会调用finalize()方法。如果在finalize()方法中引发异常会发生什么?

垃圾回收器是否会继续释放内存,还是会暂停该对象的进程?


6
为什么你在Java代码中写finalize()方法?这在大多数情况下都是不好的习惯。 - user177800
2
不,我没有编写过这样的方法,只是为了了解。 - Kumar
2个回答

11
如果异常在try-catch语句中被引发并被正确捕获,那么是的,“GC会继续进行”,就像常规程序一样。
但是,如果抛出的异常没有被处理,那么根据JSL
“如果在finalize期间抛出未捕获的异常,则忽略该异常,并终止该对象的finalize操作。”
因此,在这种情况下,“GC将停止该对象的进程”,在这种情况下,可能某些资源没有被正确释放。
顺便说一下,finalizer有两个缺点:
  • 您无法确定finalize方法是否会被执行(来自此博客

    如果垃圾收集器在释放对象的内存之前总是调用finalize,为什么要做上述操作呢?原因是垃圾收集器不总是有机会在JVM终止之前清理对象。

  • Finalizer会强制将对象提升到旧空间(这需要更长时间进行收集),并推迟GC直到运行finalizer,从而增加GC算法的开销。(参见《Java性能调优第二版》Jack Shirazi)。


是的,我觉得你说得对。那不是欺骗垃圾回收器吗?我的意思是,只有当内存没有引用时,GC才会运行。如果对象的内存保存了另一个对象的引用,这是否有资格进行GC呢?如果没有,那么finalize方法的确切目的是什么? - Kumar
1
@Kumar Finalize方法并不是用来“强制”收集对象的,而是用来释放那些无法被自动存储管理器自动释放的资源。我从未使用过这个方法,我猜它在某些罕见情况下可能会有用。正如您在博客链接中所看到的,通常您只需使用finally语句并在此处释放资源(例如关闭InputStream、Reader等)即可。 - alain.janinm
我想我需要重新表达我的评论,情况是这样的,GC正在进行中,一个对象内存即将被回收。它有finilaze方法。如果它抛出异常,那么GC将不会清除内存,这不是Java中的漏洞吗?下一个问题是,一般人们写道“finalize”方法用于清理资源,那么我的问题是,如果一个对象符合GC的条件,它会引用任何资源吗?如果是,那么它将如何被视为没有引用而被GC处理? - Kumar
1
@Kumar,我认为你错了,如果发生异常,finalization就不会正常结束,但是我猜如果没有更多的强引用处理,对象仍然可以被收集。顺便说一句,这不应该发生,如果你真的想使用finalize,请确保你的代码很干净...关于你的第二个问题,目的是清理引用,这样当关闭所有资源时,就不再有引用,对象就可以被GC。这也让我想起了“对象岛”,看一下:https://dev59.com/fGTWa4cB1Zd3GeqPEIZd - alain.janinm
1
博客链接已损坏。 - Yang Bo

0

澄清一下,这个总结非常不完整、不准确,并且歪曲了实际发生的情况。 - user177800
请加入下面的讨论,以探讨更多内容。 - Kumar
@Jarrod:你说得对,抱歉——我的回答太仓促了。我试图表达我的理解,即如果抛出异常,对象仍将被收集。我已经删除了无用的摘要。 - Martin Wilson
@Kumar,仅供记录,这个网站不是用来进行讨论的,而是用来提问和回答问题的。讨论严格属于离题。 - user177800

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接