2

终结器不是析构函数,终结器是无用的。

据我所知,很多 Java 资源对象都在 finalize() 上“以防万一”。
这似乎是一种过于宽容的态度,可能会导致错误。

您至少要做的是 finalize 记录错误(在最终确定时未处置的资源)并将它们打印到标准输出然后处置。
一种更严格的态度可能是对例外情况进行处理。我不一定要实现这样的限制性资源对象,但我想知道如何去做。

但是在 Java 中,终结器中抛出的异常被忽略(然后对象被放回列表中以再次终结)。有没有办法实现这样的事情?如果创建对象的线程仍然存在(或者如果不存在,则可能是父线程?

还!!!!!其他 gc 语言(尤其是 C#、python 等)如何处理资源终结(它们通常是否为资源类实现“以防万一处置”?),从终结器中抛出,向其他线程提供例外。(注意:我不太关心使用/使用糖来调用 dispose 方法或接受自动关闭资源的闭包的方法,我对终结器所扮演的角色以及终结器的错误传播很感兴趣)。

4

2 回答 2

1

终结器在专用线程中调用,因此抛出异常或错误不会实现任何目标,因为您无法在代码或线程之一中捕获异常。

如果您想将异常传递给另一个线程,您可以通过多种方式执行此操作。但是,我不清楚您将在另一个线程中做什么,您将在当前线程中做什么。即,当您可以让当前线程记录消息时,为什么要创建异常以传递给另一个线程以转换为日志消息。

于 2011-09-10T11:06:32.807 回答
0

终结器本身有很多缺点,从创建对象需要更长的时间到在终结器线程调用 finalize 方法之前不释放资源等等。

使用它的唯一原因是要采取预防措施来处理资源,例如 InputStream 有导致 close() 的方法,现在这可能永远不会被调用。另一种必须使用它的情况是在使用本机时。绝对没有其他情况应该这样做。

现在,您希望实现上述内容的问题是:有一个带有 finalize() 方法的对象。现在,当没有对对象的强引用时,将其发送给垃圾收集。现在它从它的入口表中检查这个特定的对象是否有一个 finalize() 方法(在最初创建对象时记录了该方法)。现在,当终结器线程运行 finalize() 方法时,在该方法内部有一段代码最终导致该方法具有强引用。

下次调用同一个对象进行垃圾回收时,第二次不会将该对象发送到终结器队列(默认情况下,没有对象可以多次进入终结器队列),因此第二次不调用 finalize() 方法. 这可能会导致巨大的问题。

因此,如果您正在处理某些事情,请确保您在 finalize() 方法之外执行它,而不是在 finalize() 中执行它,因为它只会导致问题而不是其他

于 2011-09-10T10:45:24.203 回答