OutOfMemory Exception
Martin Pernollet
martin.pernollet at protonmail.com
Mon Jan 23 11:21:39 UTC 2023
Thank you once again for your prompt reply! I fixed thanks to your advices.
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.
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.
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.
Re-reading your documentation, I wonder if it is better to use instead SegmentScope.auto() ?
Cheers,
Martin
------- Original Message -------
Le lundi 23 janvier 2023 à 11:19, Maurizio Cimadamore <maurizio.cimadamore at oracle.com> a écrit :
> Hi Martin,
> 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:
>
> -XX:MaxDirectMemorySize=<size>
>
> 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).
>
> 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.
>
> 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.
>
>> I can not unload() the MemorySegment when I am done using it (but this was also not possible in JDK17).
>
> 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.
>
> Maurizio
>
> On 22/01/2023 17:09, Martin Pernollet wrote:
>
>> Hi,
>>
>> After switching PanamaGL from JDK17 to JDK19, I am facing an OutOfMemory exception.
>>
>> 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.
>>
>> This allocation
>>
>> intnBytes=width*height*channels;
>>
>> MemorySegmentpixelsRead= MemorySegment.allocateNative(nBytes,scope);
>>
>> gl.glReadPixels(0,0,width,height,format,textureType,pixelsRead);
>>
>> Fails as follow
>>
>> java.lang.OutOfMemoryError: Cannot reserve 2169600 bytes of direct buffer memory (allocated: 4293080163, limit: 4294967296)
>>
>> at java.base/java.nio.Bits.reserveMemory(Bits.java:178)
>>
>> at java.base/java.nio.Buffer$1.reserveMemory(Buffer.java:860)
>>
>> at java.base/jdk.internal.foreign.NativeMemorySegmentImpl.makeNativeSegment(NativeMemorySegmentImpl.java:122)
>>
>> at java.base/java.lang.foreign.MemorySegment.allocateNative(MemorySegment.java:965)
>>
>> at java.base/java.lang.foreign.MemorySegment.allocateNative(MemorySegment.java:942)
>>
>> 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.
>>
>> [Capture d’écran 2023-01-22 à 17.48.40.png]
>>
>> The behavior is the same for all possible scopes provided by MemorySession (global, openConfined, openShared, openImplicit.
>>
>> One thing : I can not unload() the MemorySegment when I am done using it (but this was also not possible in JDK17).
>>
>> How could I track this memory leak? How could I ensure that useless memory get destroyed?
>>
>> Thanks in advance,
>>
>> Martin
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/panama-dev/attachments/20230123/954d6f97/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Capture d??cran 2023-01-22 ? 17.48.40.png
Type: image/png
Size: 36259 bytes
Desc: not available
URL: <https://mail.openjdk.org/pipermail/panama-dev/attachments/20230123/954d6f97/Capturedcran2023-01-2217.48.40-0001.png>
More information about the panama-dev
mailing list