I'm the idiot who has been doing Java for years and forgot to close and caused an error.
When performing continuous load tests on a server under development, the phenomenon that the application behaves strangely over time occurred. There was no problem with the CPU or memory usage and the cause remained unknown, but if I left it for a week or two, the application died with an error like "File cannot be opened anymore" in the log. .. After that, when the application checked the number of open file descriptors, it was confirmed that the maximum number of file descriptors that could be opened per process was reached.
return Files.list(Paths.get(dirPathStr)).map(path -> path.getFileName().toString())
.collect(Collectors.toSet());
The code in question is above. A method that returns a list of filenames in a directory using the Stream API, but the directory opened by Files.list ()
is not closed.
Even if I forget to close, I think that the memory itself will be released by GC, but the file descriptors will not be released, so the number of file descriptors will continue to increase each time it is executed.
By the way, when using Eclipse for the development environment (Scanner class etc.), if you forget to close in the instance of the class that opens the file, it will warn you, but (as of Eclipse 4.7) the above code does not warn you. why……
try (Stream<Path> paths = Files.list(Paths.get(dirPathStr))) {
return paths.map(path -> path.getFileName().toString()).collect(Collectors.toSet());
}
I tried to close it properly. The increase in file descriptors no longer occurs, and the application works fine.
Lessons below
Recommended Posts