垃圾收集可以关闭吗?

时间:2011-11-30 06:01:09

标签: java garbage-collection

close()对象被垃圾回收时,是否会调用Closeable接口的Closeable方法? [在java 6.0中]

我有一个静态变量,它是一个资源(数据库连接)。由于这是一个静态资源,因此无法正确调用close()

4 个答案:

答案 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 }
}