<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
OK thanks Philippe, and Larry -</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
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-)</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
I created a JBS issue: https://bugs.openjdk.org/browse/JDK-8358088</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Thanks!</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Kevin</div>
<div id="appendonsend"></div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> Philippe Marschall <kustos@gmx.net><br>
<b>Sent:</b> Thursday, May 29, 2025 5:47 PM<br>
<b>To:</b> Kevin Walls <kevin.walls@oracle.com>; serviceability-dev@openjdk.java.net <serviceability-dev@openjdk.java.net><br>
<b>Subject:</b> [External] : Re: VirtualMachineImpl.checkCatchesAndSendQuitTo leaks file handles</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText"><br>
<br>
<br>
On 29.05.25 12:21, Kevin Walls wrote:<br>
> Hi --<br>
> <br>
> 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?<br>
> I'm not seeing a leak when calling a line like this over and over in a tight loop:<br>
>    final var cmdline = Files.lines(path).findFirst();<br>
<br>
I believe it is persistent until the Cleaner of FileChannel closes it. <br>
The #line Javadoc [1] mentions the need to close<br>
<br>
 > This method must be used within a try-with-resources statement or<br>
 > similar control structure to ensure that the stream's open file is<br>
 > closed promptly after the stream's operations have completed.<br>
<br>
The Stream class Javadoc [2] explicitly mentions #lines as well<br>
<br>
 > Generally, only streams whose source is an IO channel, such as those<br>
 > returned by Files.lines(Path), will require closing. If a stream does<br>
 > require closing, it must be opened as a resource within a<br>
 > try-with-resources statement or similar control structure to ensure<br>
 > that it is closed promptly after its operations have completed.<br>
<br>
If I run something like the code below I get <br>
java.nio.file.FileSystemException: marker: Too many open files. You can <br>
also lower the number, set a breakpoint at System.out.println and check <br>
/proc/<pid>/fd<br>
<br>
<br>
Path marker = Path.of("marker");<br>
if (!Files.exists(marker)) {<br>
   Files.writeString(marker, "line1");<br>
}<br>
// usually over the max fd limit<br>
int fileCount = 100_000;<br>
// prevent streams from being garbage collected and cleaner to run and <br>
close fd<br>
List<Stream<?>> streams = new ArrayList<>(fileCount);<br>
for (int i = 0; i < fileCount; i++) {<br>
   Stream<String> stream = Files.lines(marker);<br>
   streams.add(stream);<br>
   Optional<String> firstLine = stream.findFirst();<br>
   if (firstLine.isPresent()) {<br>
     if (firstLine.get().hashCode() == 42) {<br>
       System.out.println('x');<br>
     }<br>
   }<br>
}<br>
System.out.println(streams.hashCode());<br>
<br>
  [1] <br>
<a href="https://docs.oracle.com/en/java/javase/24/docs/api/java.base/java/nio/file/Files.html#lines(java.nio.file.Path)">https://docs.oracle.com/en/java/javase/24/docs/api/java.base/java/nio/file/Files.html#lines(java.nio.file.Path)</a>
<br>
  [2] <br>
<a href="https://docs.oracle.com/en/java/javase/24/docs/api/java.base/java/util/stream/Stream.html">https://docs.oracle.com/en/java/javase/24/docs/api/java.base/java/util/stream/Stream.html</a>
<br>
<br>
Regards<br>
Philippe<br>
</div>
</span></font></div>
</body>
</html>