Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
menu mobile close menu
Проверка проектов
Дополнительная информация
toggle menu Оглавление

V6127. Closeable object is not closed. This may lead to a resource leak.

20 Май 2025

Анализатор обнаружил, что объект, реализующий интерфейс Closeable, не закрывается во всех путях исполнения.

Интерфейс Closeable сигнализирует о том, что объект содержит в себе данные, которые можно закрыть. Такие данные именуются ресурсами. Ими могут быть файлы или открытые соединения.

В случае, если пропадёт ссылка на объект, который удерживает ресурс, закрыть его не получится. Это может привести к утечке памяти, ресурса ОС или другим негативным последствиям.

В данном примере открытый файл не закрывают после использования:

public void objectIsNotClosed(File f) {
  try {
    FileInputStream fis = new FileInputStream(f); // <=
    int data;
    while ((data = fis.read()) != -1) {
      System.out.print((char) data);
    }
  } catch (IOException e) {
    // Exception handling
  }
}

Объект не закрывается в блоке try, и после выхода из него возможности закрыть файловый поток не будет.

Чтобы избежать утечки дескриптора, необходимо у объекта файлового потока вызвать метод close:

public void objectIsClosedInFinally(File f)  {
  FileInputStream fis = null;
  try {
    fis = new FileInputStream(f); 
    int data;
    while ((data = fis.read()) != -1) {
      System.out.print((char) data);
    }
  } catch (IOException e) {
    // Exception handling
  } finally {
    if (fis != null) {
      try {
        fis.close();
      } catch (IOException e) {
        // Exception handling
      }
    }
  }
}

Также в Java 7 появилась более лаконичная и удобная возможность управлять ресурсами — try-with-resources. Подробнее про неё можно прочитать в документации.

Важно отметить, что в ней Oracle рекомендуют использовать именно try-with-resources, нежели предыдущий способ закрытия ресурса.

Предыдущий пример с использованием try-with-resources:

public void objectIsClosed(File f) {
  try (FileInputStream fis = new FileInputStream(f)){
    int data;
    while ((data = fis.read()) != -1) {
      System.out.print((char) data);
    }
  } catch (IOException e) {
    // Exception handling
  }
}

Также в рамках диагностики рассматривается случай, когда Closeable объект создаётся в конструкторе, который потенциально может выбросить исключение. Такая реализация не является безопасной, потому что в случае выброса исключения Closeable объект создастся, но ссылка на него будет утрачена, и не будет возможности его закрыть.

Выявляемые диагностикой ошибки классифицируются согласно ГОСТ Р 71207–2024 как критические и относятся к типу: Ошибки утечек памяти, незакрытых файловых дескрипторов и дескрипторов сетевых соединений [* см. примечание касательно языков C#, Java].

Данная диагностика классифицируется как:

Взгляните на примеры ошибок, обнаруженных с помощью диагностики V6127.