Vazamento de recurso em Files.list (caminho dir) quando o fluxo não é explicitamente fechado?
Recentemente, escrevi um pequeno aplicativo que verificava periodicamente o conteúdo de um diretório. Depois de um tempo, o aplicativo travou devido a muitos identificadores de arquivos abertos. Após alguma depuração, encontrei o erro na seguinte linha:
Files.list(Paths.get(destination)).forEach(path -> {
// To stuff
});
Em seguida, verifiquei o javadoc (provavelmente deveria ter feito isso antes) quanto aFiles.list
e encontrou:
* <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
Para mim, "disposição oportuna" ainda parece que os recursos serão liberados eventualmente, antes que o aplicativo seja encerrado. Examinei o código JDK (1.8.60), mas não consegui encontrar nenhuma dica sobre os identificadores de arquivo abertos porFiles.list
sendo liberado novamente.
Criei um pequeno aplicativo que chama explicitamente o coletor de lixo depois de usarFiles.list
como isso:
while (true) {
Files.list(Paths.get("/")).forEach(path -> {
System.out.println(path);
});
Thread.sleep(5000);
System.gc();
System.runFinalization();
}
Quando verifiquei, o arquivo aberto lida comlsof -p <pid>
Eu ainda podia ver a lista de identificadores de arquivos abertos para "/" ficar cada vez mais longos.
Minha pergunta agora é: Existe algum mecanismo oculto que acabe fechando e não seja mais utilizado identificadores de arquivos abertos nesse cenário? Ou esses recursos nunca são descartados e o javadoc é um pouco eufemístico quando se fala em "descarte oportuno dos recursos do sistema de arquivos"?