<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<p><br>
</p>
<div class="moz-cite-prefix">On 23/01/2023 11:21, Martin Pernollet
wrote:<br>
</div>
<blockquote type="cite" cite="mid:iaYE-umP1olMnAInxhUq4vkmpMsTMOGGkZFyyl9s2DPBciz4u16X45kApRydvmJwdD_JPrabkhKQsv2ZfII1KOIOwfb52WihjZwWAiYb4e4=@protonmail.com">
<div style="font-family: Arial; font-size: 14px;">Thank you once
again for your prompt reply! I fixed thanks to your advices. </div>
<div style="font-family: Arial; font-size: 14px;"><br>
</div>
<div style="font-family: Arial; font-size: 14px;">In the my
previous version on JDK17, the culprit loop was invoking
ResourceScope.newImplicit() any time a memory segment was
required, without keeping the created scope instance. I was not
calling scope.close() neither segment.unload() and everything
was fine.</div>
<div style="font-family: Arial; font-size: 14px;">When upgrading
to JDK19 I made the MemorySession (formerly ResourceScope)
shared by all calls to the culprit loop at the instance level. I
assume that doing this change prevent the MemorySession being
collected by the GC, leading to all MemorySegment to stay in
memory.</div>
</blockquote>
Yes, this was indeed the likely culprit.<br>
<blockquote type="cite" cite="mid:iaYE-umP1olMnAInxhUq4vkmpMsTMOGGkZFyyl9s2DPBciz4u16X45kApRydvmJwdD_JPrabkhKQsv2ZfII1KOIOwfb52WihjZwWAiYb4e4=@protonmail.com">
<div style="font-family: Arial; font-size: 14px;"><br>
</div>
<div style="font-family: Arial; font-size: 14px;">My conclusion is
that the best approach with frequent exchanges between the java
program and the OpenGL library is to create implicit sessions
for the shortest possible time. <br>
</div>
</blockquote>
<p>Or, if you know the start/end of your lifetimes, just use a
confined session:</p>
<p>```<br>
try (MemorySession session = MemorySession.openConfined()) {<br>
MemorySegment segment = session.allocate(...);<br>
...<br>
} // memory deallocated exactly here<br>
```</p>
<p>The above idiom leaves no room for guesswork as to _when_ memory
will be deallocated.<br>
</p>
<blockquote type="cite" cite="mid:iaYE-umP1olMnAInxhUq4vkmpMsTMOGGkZFyyl9s2DPBciz4u16X45kApRydvmJwdD_JPrabkhKQsv2ZfII1KOIOwfb52WihjZwWAiYb4e4=@protonmail.com">
<div style="font-family: Arial; font-size: 14px;"><br>
</div>
<div style="font-family: Arial; font-size: 14px;">Re-reading your
documentation, I wonder if it is better to use instead <span style="background-color: var(--color-canvas-subtle); color:
rgb(36, 41, 47); font-family: ui-monospace, SFMono-Regular,
"SF Mono", Menlo, Consolas, "Liberation
Mono", monospace; font-size: 13.6px; box-sizing:
border-box;">SegmentScope</span><span style="background-color:
var(--color-canvas-subtle); color: rgb(36, 41, 47);
font-family: ui-monospace, SFMono-Regular, "SF
Mono", Menlo, Consolas, "Liberation Mono",
monospace; font-size: 13.6px;">.</span><span style="background-color: var(--color-canvas-subtle); color:
var(--color-prettylights-syntax-entity); font-family:
ui-monospace, SFMono-Regular, "SF Mono", Menlo,
Consolas, "Liberation Mono", monospace; font-size:
13.6px; box-sizing: border-box;">auto</span><span style="background-color: var(--color-canvas-subtle); color:
rgb(36, 41, 47); font-family: ui-monospace, SFMono-Regular,
"SF Mono", Menlo, Consolas, "Liberation
Mono", monospace; font-size: 13.6px;">() ?</span></div>
</blockquote>
<p>In the 20 API, MemorySession.openImplicit has been replaced with
SegmentScope.auto() - but the functionality is the same.</p>
<p>If you want optimal native memory usage, I think you'd have to
try to see if you can come up with a definition of where the
boundaries of your native allocations are.</p>
<p>(Btw, I'm in the process of sharing a document/writeup on
lifetimes, which might help understanding what are the memory
management options provided by the FFM API, stay tuned).</p>
<p>Cheers<br>
Maurizio<br>
</p>
<blockquote type="cite" cite="mid:iaYE-umP1olMnAInxhUq4vkmpMsTMOGGkZFyyl9s2DPBciz4u16X45kApRydvmJwdD_JPrabkhKQsv2ZfII1KOIOwfb52WihjZwWAiYb4e4=@protonmail.com">
<div style="font-family: Arial; font-size: 14px;"><span style="background-color: var(--color-canvas-subtle); color:
rgb(36, 41, 47); font-family: ui-monospace, SFMono-Regular,
"SF Mono", Menlo, Consolas, "Liberation
Mono", monospace; font-size: 13.6px;"><br>
</span></div>
<div style="font-family: Arial; font-size: 14px;">Cheers,</div>
<div style="font-family: Arial; font-size: 14px;"><br>
</div>
<div style="font-family: Arial; font-size: 14px;">Martin</div>
<div class="protonmail_signature_block" style="font-family: Arial;
font-size: 14px;">
<div class="protonmail_signature_block-user
protonmail_signature_block-empty"> </div>
<div class="protonmail_signature_block-proton"><br>
</div>
</div>
<div class="protonmail_quote"> ------- Original Message -------<br>
Le lundi 23 janvier 2023 à 11:19, Maurizio Cimadamore
<a class="moz-txt-link-rfc2396E" href="mailto:maurizio.cimadamore@oracle.com"><maurizio.cimadamore@oracle.com></a> a écrit :<br>
<br>
<blockquote class="protonmail_quote" type="cite">
<p>Hi Martin,<br>
the OOM you are getting is not a Java heap OOM. It is caused
by the default limit set for off-heap memory. This is
controlled by the same option used for increasing memory
available for direct byte buffer (hence the exception
message), namely:<br>
</p>
<div style="background-color:#ffffff;color:#000000;font-family:'Source
Code Pro',monospace;font-size:11.3pt;">
<pre><span style="color:#808080;font-style:italic;">-XX:MaxDirectMemorySize=<size>
</span></pre>
</div>
<div class="moz-cite-prefix"><br>
</div>
<div class="moz-cite-prefix">For this reason, I doubt that
what you see on VisualVM correlates with the exception you
are seeing (in fact the seesaw pattern you attached seems to
show that on-heap memory usage is quite stable).</div>
<div class="moz-cite-prefix"><br>
</div>
<div class="moz-cite-prefix">As to the actual causes, if your
application is using openConfined/openShared (w/o a cleaner
parameter!), then, assuming it still calls
"MemorySession::close" in the same places where it did in
17, nothing should have changed (in fact, the underlying
implementation between 17 and 19 did not change much at
all). In that case, all the memory segments associated with
the session have their off-heap memory deallocated when the
session is closed.<br>
</div>
<div class="moz-cite-prefix"><br>
</div>
<div class="moz-cite-prefix">If you are using openImplicit, or
openConfined/Shared (with a cleaner parameter!) then you are
at the mercy of the GC - which means that you should make
sure that the implicit session containing no-longer needed
data is truly unreachable from within your application. <br>
</div>
<div class="moz-cite-prefix"><br>
</div>
<div class="moz-cite-prefix">
<blockquote type="cite"><span> I can not unload() the
MemorySegment when I am done using it (but this was also
not possible in JDK17).</span></blockquote>
<br>
You can - but you have to plan ahead - e.g. if you need to
allocate a bunch of segments, then do something with them,
and then free them - then you need a temporary session where
to allocate those segments, and use a try-with-resource on
the temp session object.<br>
</div>
<div class="moz-cite-prefix"><br>
</div>
<div class="moz-cite-prefix">Maurizio<br>
</div>
<br>
<div class="moz-cite-prefix">On 22/01/2023 17:09, Martin
Pernollet wrote:<br>
</div>
<blockquote type="cite">
<div style="font-family: Arial; font-size: 14px;">Hi,</div>
<div style="font-family: Arial; font-size: 14px;"><br>
</div>
<div style="font-family: Arial; font-size: 14px;">After
switching PanamaGL from JDK17 to JDK19, I am facing an
OutOfMemory exception.</div>
<div style="font-family: Arial; font-size: 14px;"><br>
</div>
<div style="font-family: Arial; font-size: 14px;">The part
where this occurs is in the loop that performs offscreen
rendering and then copy the result to a BufferedImage
later used for onscreen rendering.</div>
<div style="font-family: Arial; font-size: 14px;"><br>
</div>
<div style="font-family: Arial; font-size: 14px;">This
allocation </div>
<div style="font-family: Arial; font-size: 14px;">
<div style="background-color:#2f2f2f;padding-left:2px">
<div style="color:#aaaaaa;background-color:#2f2f2f;font-family:"Menlo";font-size:12pt;white-space:nowrap">
<p><span style="color:#d9e8f7"> </span><span style="color:#80f2f6"></span></p>
<div style="background-color:#2f2f2f;padding-left:2px">
<div style="color:#aaaaaa;background-color:#2f2f2f;font-family:"Menlo";font-size:12pt">
<p><span style="color:#d9e8f7"> </span><span style="color:#cc6c1d">int</span><span style="color:#d9e8f7"> </span><span style="color:#f2f200">nBytes</span><span style="color:#d9e8f7"> </span><span style="color:#e6e6fa">=</span><span style="color:#d9e8f7"> </span><span style="color:#66e1f8">width</span><span style="color:#d9e8f7"> </span><span style="color:#e6e6fa">*</span><span style="color:#d9e8f7"> </span><span style="color:#66e1f8">height</span><span style="color:#d9e8f7"> </span><span style="color:#e6e6fa">*</span><span style="color:#d9e8f7"> </span><span style="color:#66e1f8">channels</span><span style="color:#e6e6fa">;</span></p>
</div>
</div>
MemorySegment<span style="color:#d9e8f7"> </span><span style="color:#f2f200">pixelsRead</span><span style="color:#d9e8f7"> </span><span style="color:#e6e6fa">=</span><span style="color:#d9e8f7"> MemorySegment</span><span style="color:#e6e6fa">.</span><span style="color:#96ec3f;font-style:italic">allocateNative</span><span style="color:#f9faf4">(</span><span style="color:#f3ec79">nBytes</span><span style="color:#e6e6fa">,</span><span style="color:#d9e8f7"> </span><span style="color:#66e1f8">scope</span><span style="color:#f9faf4">)</span><span style="color:#e6e6fa">;</span>
<p><span style="color:#d9e8f7"> </span><span style="color:#79abff">gl</span><span style="color:#e6e6fa">.</span><span style="color:#80f6a7">glReadPixels</span><span style="color:#f9faf4">(</span><span style="color:#6897bb">0</span><span style="color:#e6e6fa">,</span><span style="color:#d9e8f7"> </span><span style="color:#6897bb">0</span><span style="color:#e6e6fa">,</span><span style="color:#d9e8f7"> </span><span style="color:#66e1f8">width</span><span style="color:#e6e6fa">,</span><span style="color:#d9e8f7"> </span><span style="color:#66e1f8">height</span><span style="color:#e6e6fa">,</span><span style="color:#d9e8f7"> </span><span style="color:#66e1f8">format</span><span style="color:#e6e6fa">,</span><span style="color:#d9e8f7"> </span><span style="color:#66e1f8">textureType</span><span style="color:#e6e6fa">,</span><span style="color:#d9e8f7"> </span><span style="color:#f3ec79">pixelsRead</span><span style="color:#f9faf4">)</span><span style="color:#e6e6fa">;</span></p>
</div>
</div>
Fails as follow</div>
<div style="font-family: Arial; font-size: 14px;">
<div style="background-color:#2f2f2f;padding-left:2px">
<div style="color:#cccccc;background-color:#2f2f2f;font-family:"Menlo";font-size:12pt;white-space:nowrap">
<p><span style="color:#e11e46">java.lang.OutOfMemoryError:
Cannot reserve 2169600 bytes of direct buffer
memory (allocated: 4293080163, limit: 4294967296)</span></p>
<p><span style="color:#e11e46"> at
java.base/java.nio.Bits.reserveMemory(</span><span style="color:#6fc5ee;text-decoration:underline;text-decoration-style:solid">Bits.java:178</span><span style="color:#e11e46">)</span></p>
<p><span style="color:#e11e46"> at
java.base/java.nio.Buffer$1.reserveMemory(</span><span style="color:#6fc5ee;text-decoration:underline;text-decoration-style:solid">Buffer.java:860</span><span style="color:#e11e46">)</span></p>
<p><span style="color:#e11e46"> at
java.base/jdk.internal.foreign.NativeMemorySegmentImpl.makeNativeSegment(</span><span style="color:#6fc5ee;text-decoration:underline;text-decoration-style:solid">NativeMemorySegmentImpl.java:122</span><span style="color:#e11e46">)</span></p>
<p><span style="color:#e11e46"> at
java.base/java.lang.foreign.MemorySegment.allocateNative(</span><span style="color:#6fc5ee;text-decoration:underline;text-decoration-style:solid">MemorySegment.java:965</span><span style="color:#e11e46">)</span></p>
<p><span style="color:#e11e46"> at
java.base/java.lang.foreign.MemorySegment.allocateNative(</span><span style="color:#6fc5ee;text-decoration:underline;text-decoration-style:solid">MemorySegment.java:942</span><span style="color:#e11e46">)</span></p>
</div>
</div>
</div>
<div style="font-family: Arial; font-size: 14px;"><br>
</div>
<div style="font-family: Arial; font-size: 14px;">As shown
on the VisualVM screenshot the heap grows at the beginning
but is then freed. The exception happens when the heap
reduces suddenly on the chart.</div>
<div style="font-family: Arial; font-size: 14px;"><br>
</div>
<div style="font-family: Arial; font-size: 14px;"><img class="proton-embedded" alt="Capture d’écran 2023-01-22
à 17.48.40.png" src="cid:part1.a0g27T1J.hrzRIrHo@oracle.com"> </div>
<div style="font-family: Arial; font-size: 14px;"><br>
</div>
<div style="font-family: Arial; font-size: 14px;">
<div><span>The behavior is the same for all possible
scopes provided by MemorySession (global,
openConfined, openShared, openImplicit.<br>
</span></div>
<div><span><br>
</span></div>
<div><span>One thing : I can not unload() the
MemorySegment when I am done using it (but this was
also not possible in JDK17).</span></div>
</div>
<div style="font-family: Arial; font-size: 14px;"><br>
</div>
<div style="font-family: Arial; font-size: 14px;"><b>How
could I track this memory leak? How could I ensure that
useless memory get destroyed?</b></div>
<div style="font-family: Arial; font-size: 14px;"><br>
</div>
<div style="font-family: Arial; font-size: 14px;">Thanks in
advance,</div>
<div style="font-family: Arial; font-size: 14px;"><br>
</div>
<div style="font-family: Arial; font-size: 14px;">Martin</div>
<div style="font-family: Arial; font-size: 14px;" class="protonmail_signature_block">
<div class="protonmail_signature_block-user
protonmail_signature_block-empty"> </div>
<div class="protonmail_signature_block-proton"><br>
</div>
</div>
</blockquote>
</blockquote>
<br>
</div>
</blockquote>
</body>
</html>