OK thanks Philippe, and Larry - I can't provoke a problem as it stands but yes it would be good to take the recommendation of the API Note, that should keep us efficient. 8-)
I created a JBS issue: https://bugs.openjdk.org/browse/JDK-8358088 Thanks! Kevin ________________________________ From: Philippe Marschall <kus...@gmx.net> Sent: Thursday, May 29, 2025 5:47 PM To: Kevin Walls <kevin.wa...@oracle.com>; serviceability-...@openjdk.java.net <serviceability-...@openjdk.java.net> Subject: [External] : Re: VirtualMachineImpl.checkCatchesAndSendQuitTo leaks file handles On 29.05.25 12:21, Kevin Walls wrote: > Hi -- > > Just to be clear, is this an actual persistent leak that we can observe, or > is it that we could close earlier with try-with-resources? > I'm not seeing a leak when calling a line like this over and over in a tight > loop: > final var cmdline = Files.lines(path).findFirst(); I believe it is persistent until the Cleaner of FileChannel closes it. The #line Javadoc [1] mentions the need to close > This method must be used within a try-with-resources statement or > similar control structure to ensure that the stream's open file is > closed promptly after the stream's operations have completed. The Stream class Javadoc [2] explicitly mentions #lines as well > Generally, only streams whose source is an IO channel, such as those > returned by Files.lines(Path), will require closing. If a stream does > require closing, it must be opened as a resource within a > try-with-resources statement or similar control structure to ensure > that it is closed promptly after its operations have completed. If I run something like the code below I get java.nio.file.FileSystemException: marker: Too many open files. You can also lower the number, set a breakpoint at System.out.println and check /proc/<pid>/fd Path marker = Path.of("marker"); if (!Files.exists(marker)) { Files.writeString(marker, "line1"); } // usually over the max fd limit int fileCount = 100_000; // prevent streams from being garbage collected and cleaner to run and close fd List<Stream<?>> streams = new ArrayList<>(fileCount); for (int i = 0; i < fileCount; i++) { Stream<String> stream = Files.lines(marker); streams.add(stream); Optional<String> firstLine = stream.findFirst(); if (firstLine.isPresent()) { if (firstLine.get().hashCode() == 42) { System.out.println('x'); } } } System.out.println(streams.hashCode()); [1] https://docs.oracle.com/en/java/javase/24/docs/api/java.base/java/nio/file/Files.html#lines(java.nio.file.Path) [2] https://docs.oracle.com/en/java/javase/24/docs/api/java.base/java/util/stream/Stream.html Regards Philippe