Закрываемый в сборке мусора? - PullRequest
6 голосов
/ 30 ноября 2011

Метод close() интерфейса Closeable вызывается при сборке мусора для объекта Closeable?[в Java 6.0]

У меня есть статическая переменная, которая является ресурсом (соединение с базой данных).Поскольку это статический ресурс, нет правильного места для явного вызова close().

Ответы [ 4 ]

8 голосов
/ 30 ноября 2011

Быстрый ответ: нет. 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 не гарантирует, что когда-либо вызовет этот метод. То есть вы никогда не должны использовать его для обработки ресурсов; то, что вы видите выше, является сетью безопасности, которая делает утечки обработчика файлов менее разрушительными.

Еще одна проблема будет, статическое поле не будет собирать мусор - то есть, пока ваш класс виден. Таким образом, у вас нет шансов использовать финализацию.

Однако вы можете использовать Runtime.addShutdownHook() - это добавит еще один уровень защитных сетей в ваше приложение, что даст вам возможность корректно закрыть соединение при выходе. Учитывая, что вы используете статическое поле, срок службы вашего соединения, скорее всего, будет таким же, как и у JVM.

Я бы порекомендовал пересмотреть подход.

1 голос
/ 30 ноября 2011

Возможно, вы могли бы использовать финализация ?

0 голосов
/ 30 ноября 2011

Это зависит от реализации интерфейса "Closeable", от того, как он хочет обрабатывать сборку мусора. FileInputStream , например, реализует метод Object # finalize () для вызова метода Closeable # close ().

0 голосов
/ 30 ноября 2011

если вы не закроете соединение, это приведет к утечке памяти соединения; если только сервер приложений / веб-сервер не выключен. Вы можете закрыть все ваши соединения, вызвав пользовательский метод close или использовать 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 }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...