<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>