Java: создание нулевой ссылки после закрытия потока - PullRequest
6 голосов
/ 22 марта 2010

Является ли хорошей практикой установка нулевых ссылок на потоки после их закрытия? Будет ли это освобождать ресурсы каким-либо образом?

Пример:

BufferedReader input= new BufferedReader(new FileReader("myfile.txt"));

// code

input.close();
input = null;

// possible more code

Ответы [ 6 ]

7 голосов
/ 22 марта 2010

Нет, это плохая практика. ИМО, вам даже стоит подумать о создании переменной final.

Обработка ресурсов должна обрабатываться стандартным acquire(); try { use(); } finally { release(); } способом. В этом случае:

final Reader rawIn = new FileReader("myfile.txt"); // Character encoding??
try {
    BufferedReader in = new BufferedReader(rawIn);

    // code

} finally {
    rawIn.close();
}

На самом деле этот код выбирает любую кодировку символов, установленную по умолчанию. Я предлагаю быть явным с определенным жестко закодированным набором символов или параметром сверху.

final InputStream rawIn = new FileInputStream("myfile.txt");
try {
    BufferedReader in = new BufferedReader(
        new InputStreamReader(rawIn, "UTF-8")
    );

    // code

} finally {
    rawIn.close();
}

Вы не должны создавать потоки / программы чтения обертки вне блока try (и до назначения ресурса), потому что они могут выдать. Точно так же их закрытие может выдать (на самом деле это была ошибка в BufferedOutputStream, которая могла выдать flush). Некоторые входные потоки могут иметь другие ресурсы, поэтому вам нужно два try { ... finally { x.close(); } s.

Для вывода вы обычно должны flush при нормальном ходе событий. Но, как правило, не в исключительных случаях. На самом деле close обычно делает flush, поэтому вам не следует закрывать их в исключительном случае. Если у декораторов есть и flush, и у них есть ресурсы, вам придется улыбаться и обнажать их.

Есть очень редкие случаи, когда обнуление является хорошей идеей. Например, если переменная является единственной ссылкой на большой объект, и вы собираетесь создать новый большой объект, чтобы назначить ему, может быть лучше очистить ссылку, чтобы позволить старому быть восстановленным перед выделением нового.

5 голосов
/ 22 марта 2010

Не требуется.Просто input.close() достаточно.Помните, всегда разумно делать это внутри блока finally.И перед вызовом close() лучше сделать нулевую проверку, как это

finally{
  if(input!=null){
    input.close();
  }
}
3 голосов
/ 22 марта 2010

Может сделать сам объект Stream пригодным для сборки мусора, но

  1. В большинстве случаев оно в любом случае сразу выходит за рамки
  2. количество памяти, "освобожденной" таким образом, совершенно незначительно
1 голос
/ 22 марта 2010

Нет, это не так. close() уже освобождает ресурс. Обычная практика такова:

Resource resource = null;
try {
    resource = new Resource();
    // ...
} finally {
    if (resource != null) try { resource.close(); } catch (ResourceException logOrIgnore) {}
}

Где Resource может быть любым внешним ресурсом, который вы хотели бы использовать, таким как InputStream, OutputStream, Reader и Writer API Java IO, но также, например, Connection, Statement и ResultSet API JDBC.

Память не является проблемой в хорошо разработанном коде. Если код покидает блок метода, он уже подходит для GC.

Вы можете изменить рефакторинг close() на служебный метод, например:

public static void close(Closeable resource) {
    if (resource != null) {
        try {
            resource.close();
        } catch (ResourceException logOrIgnore) {
            // Log it?
        }
    }
}

, который вы можете использовать следующим образом:

} finally {
    close(resource);
}

Apache Commons предоставляет несколько таких служебных методов.

1 голос
/ 22 марта 2010

Если вы вручную не управляете пулом источников (обращаясь с собственной памятью), нет необходимости обнулять входной поток. В идеале любая функция, в которой вы находитесь, мала, и ссылки на объект умрут, когда объект выйдет из области видимости, в любом случае пометив его для сборки мусора.

Я упоминаю пул ресурсов, как будто вы наивно закрываете поток, не обнуляя объект, вы можете случайно удерживать ссылку на объект, который вам на самом деле не нужен.

0 голосов
/ 22 марта 2010

В этом случае он не нужен, сборщик мусора будет его собирать.

Но назначать null не всегда плохая практика.Прочитайте статью 6 из Effective Java, глава 2

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...