<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<p>If you just want to be able to copy memory from A to B, you can
use the code you have shown, yes.</p>
<p>I'm not 100% sure of the use of the everything segment here.
Perhaps you want to do that to avoid doing
MemorySegment::ofBuffer. While I understand that, as mentioned, we
have improved that factory, so I'm not sure the creation of the
additional segment view should be problematic (e.g. it should be
escape analyzed where it matters).<br>
</p>
<p>You can also create a downcall method handle for memcpy, and then
pass to it the two pointers you want to copy. The pointers can
either be passed as memory segments, or as plain longs, depending
on how you describe the memcpy arguments to the Linker (of course
the latter is more unsafe and not really recommended, but an
option nevertheless).</p>
<p>Maurizio<br>
</p>
<p><br>
</p>
<div class="moz-cite-prefix">On 06/01/2025 13:34, Sergio Selos
wrote:<br>
</div>
<blockquote type="cite" cite="mid:CANFht85B8oKk5ie56_6gUd2JzY_zs=KZqgLNAerw7xY1efomeg@mail.gmail.com">
<div dir="ltr">
<div dir="ltr">Hi Everyone,
<div><br>
</div>
<div>Thanks for taking the time to analyze and reply to my
question. I think the classic C memcpy would solve my
problem, and I could do it through some JNI code, but I
would be happy to be able to use Panama (pure Java) instead.
I posted this question on SO and someone has suggested the
solution below using Panama. I haven't tried it yet.<br>
<br>
<a href="https://stackoverflow.com/a/79311822/28712954" moz-do-not-send="true" class="moz-txt-link-freetext">https://stackoverflow.com/a/79311822/28712954</a></div>
<div><br>
</div>
<div>
<pre class="gmail-lang-java gmail-s-code-block" style="margin-top:0px;border:0px;font-variant-numeric:inherit;font-variant-east-asian:inherit;font-variant-alternates:inherit;font-stretch:inherit;font-size-adjust:inherit;font-kerning:inherit;font-feature-settings:inherit;vertical-align:baseline;box-sizing:inherit;width:auto;max-height:600px;overflow:auto;color:rgb(12,13,14)"><code class="gmail-hljs gmail-language-java" style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;font-family:inherit;font-size-adjust:inherit;font-kerning:inherit;font-feature-settings:inherit;vertical-align:baseline;box-sizing:inherit;background-color:transparent;white-space:inherit"><span class="gmail-hljs-comment" style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;font-family:inherit;font-size-adjust:inherit;font-kerning:inherit;font-feature-settings:inherit;font-size:13px;vertical-align:baseline;box-sizing:inherit">// With FFM API:</span>
<span class="gmail-hljs-keyword" style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;font-family:inherit;font-size-adjust:inherit;font-kerning:inherit;font-feature-settings:inherit;font-size:13px;vertical-align:baseline;box-sizing:inherit">static</span> <span class="gmail-hljs-keyword" style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;font-family:inherit;font-size-adjust:inherit;font-kerning:inherit;font-feature-settings:inherit;font-size:13px;vertical-align:baseline;box-sizing:inherit">final</span> <span class="gmail-hljs-type" style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;font-family:inherit;font-size-adjust:inherit;font-kerning:inherit;font-feature-settings:inherit;font-size:13px;vertical-align:baseline;box-sizing:inherit">MemorySegment</span> <span class="gmail-hljs-variable" style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;font-family:inherit;font-size-adjust:inherit;font-kerning:inherit;font-feature-settings:inherit;font-size:13px;vertical-align:baseline;box-sizing:inherit">EVERYTHING_SEGMENT</span> <span class="gmail-hljs-operator" style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;font-family:inherit;font-size-adjust:inherit;font-kerning:inherit;font-feature-settings:inherit;font-size:13px;vertical-align:baseline;box-sizing:inherit">=</span> MemorySegment.NULL.reinterpret(Long.MAX_VALUE);
<span class="gmail-hljs-meta" style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;font-family:inherit;font-size-adjust:inherit;font-kerning:inherit;font-feature-settings:inherit;font-size:13px;vertical-align:baseline;box-sizing:inherit">@Override</span>
<span class="gmail-hljs-keyword" style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;font-family:inherit;font-size-adjust:inherit;font-kerning:inherit;font-feature-settings:inherit;font-size:13px;vertical-align:baseline;box-sizing:inherit">public</span> <span class="gmail-hljs-keyword" style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;font-family:inherit;font-size-adjust:inherit;font-kerning:inherit;font-feature-settings:inherit;font-size:13px;vertical-align:baseline;box-sizing:inherit">void</span> <span class="gmail-hljs-title gmail-function_" style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;font-family:inherit;font-size-adjust:inherit;font-kerning:inherit;font-feature-settings:inherit;font-size:13px;vertical-align:baseline;box-sizing:inherit">getByteBuffer</span><span class="gmail-hljs-params" style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;font-family:inherit;font-size-adjust:inherit;font-kerning:inherit;font-feature-settings:inherit;font-size:13px;vertical-align:baseline;box-sizing:inherit">(<span class="gmail-hljs-type" style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;font-family:inherit;font-size-adjust:inherit;font-kerning:inherit;font-feature-settings:inherit;vertical-align:baseline;box-sizing:inherit">long</span> address, ByteBuffer dst, <span class="gmail-hljs-type" style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;font-family:inherit;font-size-adjust:inherit;font-kerning:inherit;font-feature-settings:inherit;vertical-align:baseline;box-sizing:inherit">int</span> len)</span> {
<span class="gmail-hljs-keyword" style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;font-family:inherit;font-size-adjust:inherit;font-kerning:inherit;font-feature-settings:inherit;font-size:13px;vertical-align:baseline;box-sizing:inherit">if</span> (!dst.isDirect()) {
<span class="gmail-hljs-keyword" style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;font-family:inherit;font-size-adjust:inherit;font-kerning:inherit;font-feature-settings:inherit;font-size:13px;vertical-align:baseline;box-sizing:inherit">throw</span> <span class="gmail-hljs-keyword" style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;font-family:inherit;font-size-adjust:inherit;font-kerning:inherit;font-feature-settings:inherit;font-size:13px;vertical-align:baseline;box-sizing:inherit">new</span> <span class="gmail-hljs-title gmail-class_" style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;font-family:inherit;font-size-adjust:inherit;font-kerning:inherit;font-feature-settings:inherit;font-size:13px;vertical-align:baseline;box-sizing:inherit">RuntimeException</span>(<span class="gmail-hljs-string" style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;font-family:inherit;font-size-adjust:inherit;font-kerning:inherit;font-feature-settings:inherit;font-size:13px;vertical-align:baseline;box-sizing:inherit">"getByteBuffer can only take a direct byte buffer!"</span>);
}
<span class="gmail-hljs-type" style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;font-family:inherit;font-size-adjust:inherit;font-kerning:inherit;font-feature-settings:inherit;font-size:13px;vertical-align:baseline;box-sizing:inherit">long</span> <span class="gmail-hljs-variable" style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;font-family:inherit;font-size-adjust:inherit;font-kerning:inherit;font-feature-settings:inherit;font-size:13px;vertical-align:baseline;box-sizing:inherit">dstAddress</span> <span class="gmail-hljs-operator" style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;font-family:inherit;font-size-adjust:inherit;font-kerning:inherit;font-feature-settings:inherit;font-size:13px;vertical-align:baseline;box-sizing:inherit">=</span> (<span class="gmail-hljs-type" style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;font-family:inherit;font-size-adjust:inherit;font-kerning:inherit;font-feature-settings:inherit;font-size:13px;vertical-align:baseline;box-sizing:inherit">long</span>) addressField.get(dst) + dst.position();
EVERYTHING_SEGMENT.copyFrom(<span class="gmail-hljs-built_in" style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;font-family:inherit;font-size-adjust:inherit;font-kerning:inherit;font-feature-settings:inherit;font-size:13px;vertical-align:baseline;box-sizing:inherit">this</span>.segment, offset, dstAddress, len);
dst.position(dst.position() + len);
}</code></pre>
</div>
</div>
All the best,
<div><br>
</div>
<div>-Sergio</div>
<div><br>
</div>
<div><br>
<div class="gmail_quote gmail_quote_container">
<div dir="ltr" class="gmail_attr">On Mon, Jan 6, 2025 at
6:57 AM <<a href="mailto:rsmogura@icloud.com" moz-do-not-send="true" class="moz-txt-link-freetext">rsmogura@icloud.com</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi,<br>
<br>
I wonder if this concern can be because of using Arena
arena = Arena.ofConfined(), or due to @Overriding method
and inability to inline method.<br>
<br>
What do you think (sorry if I missed parts of this
discussion).<br>
<br>
Best regards,<br>
Rado<br>
<br>
> Wiadomość napisana przez Jorn Vernee <<a href="mailto:jorn.vernee@oracle.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">jorn.vernee@oracle.com</a>>
w dniu 6 sty 2025, o godz. 12:25:<br>
> <br>
> Hello,<br>
> <br>
> Have you verified that garbage is actually being
generated when using FFM?<br>
> <br>
> If I set up a test program based on your snippet [1],
and run it with -XX:CompileCommand=TraceEscapeAnalysis,...
I don't actually see any escaping allocations.<br>
> <br>
> Jorn<br>
> <br>
> [1]:<br>
> <br>
> import java.lang.foreign.Arena;<br>
> import java.lang.foreign.MemorySegment;<br>
> import java.nio.ByteBuffer;<br>
> <br>
> public class TestOfBuffer {<br>
> <br>
> long address = 0;<br>
> MemorySegment segment;<br>
> <br>
> public static void main(String[] args) {<br>
> TestOfBuffer recv = new TestOfBuffer();<br>
> recv.segment = Arena.global().allocate(100);<br>
> <br>
> ByteBuffer bb =
ByteBuffer.allocateDirect(10);<br>
> for (int i = 0; i < 20_000; i++) {<br>
> recv.payload(0, bb, 10);<br>
> bb.flip();<br>
> }<br>
> }<br>
> <br>
> public void payload(long address, ByteBuffer dst,
int len) {<br>
> if (!dst.isDirect()) {<br>
> throw new RuntimeException("getByteBuffer
can only take a direct byte buffer!");<br>
> }<br>
> <br>
> long offset = address - this.address; //
offset in our 'segment'<br>
> <br>
> // Wrap the destination ByteBuffer in a
temporary segment<br>
> // This segment's data starts at
dst.position()<br>
> MemorySegment dstSegment =
MemorySegment.ofBuffer(dst); // <====== temp memory
segment object<br>
> <br>
> // Copy from 'segment' at 'offset' →
dstSegment at offset 0 → length = 'len'<br>
> MemorySegment.copy(this.segment, offset,
dstSegment, 0, len);<br>
> dst.position(dst.position() + len);<br>
> }<br>
> }<br>
> <br>
> On 27-12-2024 02:05, Sergio Selos wrote:<br>
>> Hello,<br>
>> <br>
>> We have a project using sun.misc.Unsafe that we
are migrating to the new FFM API. The project is at <a href="https://www.github.com/coralblocks/CoralRing" rel="noreferrer" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">https://www.github.com/coralblocks/CoralRing</a><br>
>> <br>
>> For our particular systems (mostly financial low
latency systems) it is important not to create any garbage
(temp discarded instances) when receiving a message.<br>
>> <br>
>> We encountered an issue when copying from native
memory straight into a direct ByteBuffer using the FFM
API.<br>
>> <br>
>> Using sun.misc.Unsafe, copying from memory to a
ByteBuffer can be done without creating temporary objects
and garbage collector overhead. However, with the FFM API,
achieving the same does not seem currently possible
without generating garbage via a call to
MemorySegment.ofBuffer.<br>
>> <br>
>> Does the FFM dev team plan to address this issue
and provide a garbage-free way to perform this copy, like
we currently can with sun.misc.Unsafe?<br>
>> <br>
>> Maybe there is already a way and we are just
unaware how to do it.<br>
>> <br>
>> Below the current code we have with
sun.misc.Unsafe, which does not produce any garbage, and
the only way we are aware of to do it with the FFM API,
which produces garbage.<br>
>> <br>
>> Thanks and let me know if you need any more
details about this and/or if I can help with anything.<br>
>> <br>
>> All the best,<br>
>> <br>
>> -Sergio<br>
>> <br>
>> // With sun.misc.Unsafe:<br>
>> @Override<br>
>> public void getByteBuffer(long address,
ByteBuffer dst, int len) {<br>
>> if (!dst.isDirect()) {<br>
>> throw new RuntimeException("getByteBuffer
can only take a direct byte buffer!");<br>
>> }<br>
>> try {<br>
>> long dstAddress = (long)
addressField.get(dst); // get the memory address of this
ByteBuffer<br>
>> dstAddress += dst.position(); // adjust
the address for the ByteBuffer current position<br>
>> unsafe.copyMemory(address, dstAddress,
len); // copy over<br>
>> dst.position(dst.position() + len); //
adjust the ByteBuffer position to reflect the copy
operation<br>
>> } catch(Exception e) {<br>
>> throw new RuntimeException(e);<br>
>> }<br>
>> }<br>
>> <br>
>> // With FFM API:<br>
>> @Override<br>
>> public void getByteBuffer(long address,
ByteBuffer dst, int len) {<br>
>> if (!dst.isDirect()) {<br>
>> throw new RuntimeException("getByteBuffer
can only take a direct byte buffer!");<br>
>> }<br>
>> <br>
>> long offset = address - this.address; //
offset in our 'segment'<br>
>> <br>
>> try (Arena arena = Arena.ofConfined()) { //
<==== probably creating a temp object here too<br>
>> // Wrap the destination ByteBuffer in a
temporary segment<br>
>> // This segment's data starts at
dst.position()<br>
>> MemorySegment dstSegment =
MemorySegment.ofBuffer(dst, arena); // <====== temp
memory segment object<br>
>> <br>
>> // Copy from 'segment' at 'offset' →
dstSegment at offset 0 → length = 'len'<br>
>> dstSegment.copyFrom(this.segment, offset,
0, len);<br>
>> }<br>
>> dst.position(dst.position() + len);<br>
>> }<br>
>> <br>
>> <br>
>> <br>
>> <br>
>> <br>
<br>
</blockquote>
</div>
</div>
</div>
</blockquote>
</body>
</html>