V6127. Closeable object is not closed. This may lead to a resource leak.
Анализатор обнаружил, что объект, реализующий интерфейс 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 как критические и относятся к типу: Ошибки утечек памяти, незакрытых файловых дескрипторов и дескрипторов сетевых соединений. |
Данная диагностика классифицируется как: