<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<p>If MemorySegment had a free() method, anybody would be able to
free a memory segment. So, if you want to let a client just use a
memory segment, without the risk of it being freed, you would need
some kind of way to create a non-closeable view of a segment, and
you would have to do that every time you need to pass a segment to
some other code. That is what we had in the past (around the time
of JDK 14), and it lead to an awkward amount of defensive code
creating non-closeable segments, as well as GC churn for those new
objects. We moved away from that, and towards 'inadvertent free'
being impossible by design: only someone who holds an arena can
free the memory. Someone who just holds a memory segment can't.
That is an important feature (this is discussed in detail in the
document you linked to as well).<br>
</p>
<p><br>
</p>
<p>So, the API was designed around arenas governing lifetimes, not
memory segments. If you want to manage the lifetime of some
resource, Arena is the abstraction that should be used for that.
As far as your case goes: you also have the option to embrace
lifetimes, and expose them in your API. i.e. let your users
(indirectly) create and close the arenas that should be used to
manage these pointers. Doing this would also allow users to pick
the arena kind that is appropriate for them, such as confined
arenas, and also allows users to re-use the same arena multiple
times for different resources.<br>
</p>
<p><br>
</p>
<p>Regarding safety: the main issue comes from threads racing to
access & free the same memory. In a multi-threaded context, we
can not simply check liveness around accesses, as the memory could
be freed <i>during</i> the access, resulting in memory corruption
and/or crashes. Confined arenas avoid this issue by restricting
the use of the memory to a single thread.<br>
</p>
<p><br>
</p>
<p>Jorn<br>
</p>
<p><br>
</p>
<div class="moz-cite-prefix">On 17-2-2025 19:36, Benoit Daloze
wrote:<br>
</div>
<blockquote type="cite" cite="mid:SJ2PR10MB759801452564DCB05BCDE5E28FFB2@SJ2PR10MB7598.namprd10.prod.outlook.com">
<style type="text/css" style="display:none;">P {margin-top:0;margin-bottom:0;}</style>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Thank you for the quick and detailed reply.</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);">
Right, given the requirements, calling malloc() and free()
ourselves would work, and then we'd create MemorySegments with
ofAddress() + reinterpret().</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);">
Regarding safety, would there by any safety issue if:</div>
<ul style="list-style-type: disc;" data-editing-info="{"applyListStyleFromLevel":false,"unorderedStyleType":1}">
<li style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<div class="elementToProof">MemorySegment would have a free()
method, which could only be called if the MemorySegment
doesn't belong to an Arena (and throw otherwise). Or maybe
the Global Arena could behave like that.</div>
</li>
<li style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<div class="elementToProof">Slices of that MemorySegment would
remember their root MemorySegment, so that they would all
check if the root segment is freed before/around performing
accesses (e.g. like SharedSession does it).</div>
</li>
<li style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<div class="elementToProof">Slices themselves either can't
free(), or if they can they would just delegate to the root
MemorySegment.</div>
</li>
<li style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<div class="elementToProof">The root MemorySegment could be
auto-release for convenience.</div>
</li>
</ul>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Do you see any safety issue with that design?</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 guess it's quite similar to having a Shared Arena per
(non-slice) MemorySegment but without the overhead of creating
that Arena and associated objects.</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> Maurizio
Cimadamore <a class="moz-txt-link-rfc2396E" href="mailto:maurizio.cimadamore@oracle.com"><maurizio.cimadamore@oracle.com></a><br>
<b>Sent:</b> Monday, February 17, 2025 17:31<br>
<b>To:</b> Benoit Daloze <a class="moz-txt-link-rfc2396E" href="mailto:benoit.daloze@oracle.com"><benoit.daloze@oracle.com></a>;
<a class="moz-txt-link-abbreviated" href="mailto:panama-dev@openjdk.org">panama-dev@openjdk.org</a> <a class="moz-txt-link-rfc2396E" href="mailto:panama-dev@openjdk.org"><panama-dev@openjdk.org></a><br>
<b>Subject:</b> Re: Releasing MemorySegments eagerly and
efficiently</font>
<div> </div>
</div>
<div>
<p>Hi,<br>
when it comes to deallocation, I think you can summarize the
situation with efficient, shared, safe: pick two.</p>
<p><br>
You can have safe and efficient deallocation with confined
access (or, in the future, structured access).</p>
<p><br>
</p>
<p>You can have safe, but less efficient shared deallocation
with eithe letting the GC do the work (reachability-base
automatic arena) or having some more expensive handshake when
the arena is closed (shared arena).</p>
<p><br>
</p>
<p>You can have _unsafe_ efficient shared allocation: just wrap
malloc/free using the Linker API, and then use
MemorySegment::reinterpret to resize he unsafely allocated
segments accordingly. This will give you something closer to
the C feel but it is (as C is), unsafe (reinterpret is a
restricted method).<br>
</p>
<p><br>
</p>
<p>(There's also solution in the middle - by having pooling
arenas you can greatly reduce the cost of malloc/free -- but
your mileage might vary as those solutions will typically only
work best if your memory allocation is somewhat structured --
e.g. if allocation occurs in a code block).</p>
<p><br>
</p>
<p>What you end up using is up to you (and your requirements).
The FFM API supports all the above -- but of course the Arena
API, that is designed to be a safe API only gives you access
to safe way to allocate/deallocate segments.</p>
<p><br>
</p>
<p>Maurizio<br>
</p>
<p><br>
</p>
<div class="x_moz-cite-prefix">On 17/02/2025 16:19, Benoit
Daloze wrote:<br>
</div>
<blockquote type="cite">
<style type="text/css" style="display:none">p
{margin-top:0;
margin-bottom:0}</style>
<div class="x_elementToProof" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Hello panama-dev,</div>
<div class="x_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="x_elementToProof" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
We are looking at migrating from Unsafe off-heap methods to
Panama/MemorySegment.</div>
<div class="x_elementToProof" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
While migrating we hit a blocker for replacing
Unsafe#freeMemory() calls.</div>
<div class="x_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="x_elementToProof" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Specifically, we are implementing various languages like
Python and Ruby which have their own
Pointer/Buffer-like abstractions (i.e. they support
reading/writing various native types at some offset,
allocation, freeing, etc).</div>
<div class="x_elementToProof" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Some of these pointers have a known size/length and some
don't (and those that don't are allowed to read/write
anywhere, as if they had infinite length).</div>
<div class="x_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="x_elementToProof" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Some pointers/buffers themselves have auto-release semantics
and some don't (e.g. when they come back from a native
call), regardless of that these languages allow freeing them
eagerly, e.g.
<a href="https://www.rubydoc.info/gems/ffi/1.16.3/FFI/Pointer#free-instance_method" id="OWA5bf8ac37-78a9-ec4c-935b-da2e81a96692" class="x_OWAAutoLink x_moz-txt-link-freetext moz-txt-link-freetext" moz-do-not-send="true">
https://www.rubydoc.info/gems/ffi/1.16.3/FFI/Pointer#free-instance_method</a></div>
<div class="x_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="x_elementToProof" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Freeing eagerly is crucial to avoid excessive resource
consumptions (especially if the allocations are big). It's
similar to the problem of running out of file descriptors
when not closing them explicitly, hence closing
explicitly is best, otherwise one might run out of memory.</div>
<div class="x_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="x_elementToProof" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Looking at the docs, there is no
MemorySegment#free()/close() or so, and this seems
intentional based on
<a href="https://cr.openjdk.org/~mcimadamore/panama/why_lifetimes.html" id="OWAfc1a7c26-05c9-642a-783c-17481aab96a7" class="x_OWAAutoLink x_moz-txt-link-freetext moz-txt-link-freetext" moz-do-not-send="true">
https://cr.openjdk.org/~mcimadamore/panama/why_lifetimes.html</a></div>
<div class="x_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="x_elementToProof" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Instead, some Arenas can be close()'d.</div>
<div class="x_elementToProof" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Looking at Arena docs, of all 4 builtin arena types, only
Confined and Shared are allowed to be
closed explicitly/eagerly.</div>
<div class="x_elementToProof" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
In general those pointer abstractions can be accessed by
multiple threads, so Confined wouldn't work.</div>
<div class="x_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="x_elementToProof" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Using a Shared Arena per pointer/buffer allocation seems
very expensive both in footprint (need to keep various
objects alive vs just a long with Unsafe) and in performance
(though I have not benchmarked it yet against
allocateMemory+freeMemory).<br>
If also doesn't feel right because those allocations are
supposed to be individual memory allocations, not a whole
arena/pool allocation.</div>
<div class="x_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="x_elementToProof" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Therefore, what can be used to be able to free individual
MemorySegment efficiently in this context?</div>
<div class="x_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="x_elementToProof" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Maybe the Automatic arena should have a way to free
explicitly a MemorySegment?</div>
<div class="x_elementToProof" style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
I think it would make sense, as while auto-release semantics
are convenient, it's always good practice to release such
native resources eagerly rather than wait for GC.</div>
</blockquote>
</div>
</blockquote>
</body>
</html>