[External] : Re: VirtualMachineImpl.checkCatchesAndSendQuitTo leaks file handles
Philippe Marschall
kustos at gmx.net
Fri May 30 11:58:31 UTC 2025
Should I open the PR? I think we're all pretty much in agreement
regarding the fix.
Cheers
Philippe
On 29.05.25 20:59, Laurence Cable wrote:
> ignore this... apologies
>
> On 5/29/25 11:51 AM, Laurence Cable wrote:
>> https://github.com/openjdk/jdk/pull/25526
>>
>> On 5/29/25 11:05 AM, Kevin Walls wrote:
>>> 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 <kustos at gmx.net>
>>> *Sent:* Thursday, May 29, 2025 5:47 PM
>>> *To:* Kevin Walls <kevin.walls at oracle.com>; serviceability-
>>> dev at openjdk.java.net <serviceability-dev at 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
>>
>
More information about the serviceability-dev
mailing list