Утечка ресурсов в Files.list (Path dir), когда поток явно не закрыт?
Недавно я написал небольшое приложение, которое периодически проверяет содержимое каталога. Через некоторое время приложение упало из-за слишком большого количества дескрипторов открытых файлов. После некоторой отладки я обнаружил ошибку в следующей строке:
Files.list(Paths.get(destination)).forEach(path -> {
// To stuff
});
Затем я проверил Javadoc (я, вероятно, должен был сделать это раньше) дляFiles.list
и нашел:
* <p> The returned stream encapsulates a {@link DirectoryStream}.
* If timely disposal of file system resources is required, the
* {@code try}-with-resources construct should be used to ensure that the
* stream's {@link Stream#close close} method is invoked after the stream
* operations are completed
Для меня «своевременное удаление» все еще звучит так, как будто ресурсы будут выпущены в конце концов, до того, как приложение закроется. Я просмотрел код JDK (1.8.60), но не смог найти подсказки о дескрипторах файлов, открытыхFiles.list
быть освобожденным снова.
Затем я создал небольшое приложение, которое явно вызывает сборщик мусора после использованияFiles.list
как это:
while (true) {
Files.list(Paths.get("/")).forEach(path -> {
System.out.println(path);
});
Thread.sleep(5000);
System.gc();
System.runFinalization();
}
Когда я проверил дескрипторы открытого файла сlsof -p <pid>
Я все еще мог видеть список открытых файловых дескрипторов для "/", становящихся все длиннее и длиннее.
Теперь у меня вопрос: есть ли какой-нибудь скрытый механизм, который должен в конечном итоге закрывать уже не используемые дескрипторы файлов в этом сценарии? Или эти ресурсы на самом деле никогда не утилизируются, и Javadoc немного эвфемичен, когда говорит о «своевременном удалении ресурсов файловой системы»?