我对JVM中关于垃圾收集的终结器如何在这里以及互联网上的几个来源非常困惑。
根据我的理解,通常的方法是不依赖终结器来执行清理,因为无法保证何时会调用它们,或者如果应用程序完成它们是否会被调用。但是,只要应用程序处于活动状态,我仍然希望在应用程序完成时调用它们并且所有对象都不再存在。
在我的特定情况下,我有一个应用程序,其中一个类打开了与另一个资源的连接。
简化我们将
public class MyClass {
Connection connection = new Connection();
public MyClass() {
connection.open();
}
public void close() {
connection.close();
}
@Override
protected void finalize() {
connection.close();
}
}
public class Main {
public static void main(String[] args) {
MyClass instance = new MyClass();
// If I call instance.close(), application ends when it reaches end of main method
// instance.close()
// If not called, application will not end.
}
}
注意“MyClass”的封装目的,调用代码不一定需要知道(也不需要)他正在使用非托管资源。
当应用程序一直运行时会发生什么事情,我假设在没有释放它的情况下挂起了打开的连接,因为GC没有被调用(并且由于没有真正的内存压力而永远不会被调用)。
如果在应用程序完成时GC 不被调用,是否有办法保证在应用程序完成时关闭非托管资源(连接)?显然无需明确调用close。
我已经看过AutoClosable接口,这绝对是一个选项,但它仍然不能保证在应用程序完成时最终会丢弃连接。
答案 0 :(得分:1)
如果在应用程序完成时未调用GC,是否有办法保证在应用程序完成时关闭非受管资源(连接)?显然无需明确调用close。
如果你打电话(在Unix上)
kill -9 {pid}
该过程立即死亡而不通知该过程。例如,不调用finally
块。你无能为力阻止这一点。
您可以通过runFinalizersOnExit
正常关闭调用终结器,但只能在正常关闭时调用。
顺便说一句如果您拔出电源或网络连接,您也不会有优雅的断开连接,因此您无法处理此问题,您所能做的就是在优雅的关闭时进行清理()/关断。