当close()
对象被垃圾回收时,是否会调用Closeable
接口的Closeable
方法? [在java 6.0中]
我有一个静态变量,它是一个资源(数据库连接)。由于这是一个静态资源,因此无法正确调用close()
。
答案 0 :(得分:7)
快速回答:没有。 GC完全不关心Closeable
。
Java确实有protected void finalize() throws Throwable { }
方法可以覆盖 - 并且它将在GC上调用。它有点工作,例如在FileInputStream
:
/**
* Ensures that the <code>close</code> method of this file input stream is
* called when there are no more references to it.
*
* @exception IOException if an I/O error occurs.
* @see java.io.FileInputStream#close()
*/
protected void finalize() throws IOException {
if ((fd != null) && (fd != FileDescriptor.in)) {
/*
* Finalizer should not release the FileDescriptor if another
* stream is still using it. If the user directly invokes
* close() then the FileDescriptor is also released.
*/
runningFinalize.set(Boolean.TRUE);
try {
close();
} finally {
runningFinalize.set(Boolean.FALSE);
}
}
}
问题是,它产生的问题多于它的价值:例如,JVM并不能保证它会调用这个方法。也就是说,你永远不应该用它来进行资源处理;你在上面看到的是一个安全网,使文件处理程序泄漏的破坏性降低。
另一个问题是,static field will not be garbage collected - 也就是说,只要你的班级可见。所以你没有机会使用finalization。
但是,您可以使用Runtime.addShutdownHook()
- 它将为您的应用程序添加另一层安全网,让您有机会在退出时优雅地关闭连接。鉴于您正在使用静态字段,无论如何,您的连接的生命周期可能与JVM的相同。
我建议我们回顾一下这种方法。
答案 1 :(得分:1)
也许您可以使用finalization?
答案 2 :(得分:0)
它取决于“Closeable”接口的实现,它是如何处理垃圾收集的。例如,FileInputStream实现Object#finalize()方法,以调用Closeable#close()方法。
答案 3 :(得分:-1)
如果不关闭连接,将导致连接内存泄漏;除非关闭应用程序服务器/ Web服务器。 您可以通过调用自定义关闭方法或使用finalilize
来关闭所有连接public void closeConnection {
try { rs.close(); } catch (Exception e) { // TODO Auto-generated catch block }
try { ps.close(); } catch (Exception e) { // TODO Auto-generated catch block }
try { conn.close(); } catch (Exception e) { // TODO Auto-generated catch block }
}
...
finally {
try { rs.close(); } catch (Exception e) { // TODO Auto-generated catch block }
try { ps.close(); } catch (Exception e) { // TODO Auto-generated catch block }
try { conn.close(); } catch (Exception e) { // TODO Auto-generated catch block }
}