Garbage problem migrating from sun.misc.Unsafe to FFM API
Jorn Vernee
jorn.vernee at oracle.com
Mon Jan 6 11:25:05 UTC 2025
Hello,
Have you verified that garbage is actually being generated when using FFM?
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.
Jorn
[1]:
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.nio.ByteBuffer;
public class TestOfBuffer {
long address = 0;
MemorySegment segment;
public static void main(String[] args) {
TestOfBuffer recv = new TestOfBuffer();
recv.segment = Arena.global().allocate(100);
ByteBuffer bb = ByteBuffer.allocateDirect(10);
for (int i = 0; i < 20_000; i++) {
recv.payload(0, bb, 10);
bb.flip();
}
}
public void payload(long address, ByteBuffer dst, int len) {
if (!dst.isDirect()) {
throw new RuntimeException("getByteBuffer can only take a
direct byte buffer!");
}
long offset = address - this.address; // offset in our 'segment'
// Wrap the destination ByteBuffer in a temporary segment
// This segment's data starts at dst.position()
MemorySegment dstSegment = MemorySegment.ofBuffer(dst); //
<====== temp memory segment object
// Copy from 'segment' at 'offset' → dstSegment at offset 0 →
length = 'len'
MemorySegment.copy(this.segment, offset, dstSegment, 0, len);
dst.position(dst.position() + len);
}
}
On 27-12-2024 02:05, Sergio Selos wrote:
> Hello,
>
> We have a project using sun.misc.Unsafe that we are migrating to the
> new FFM API. The project is at
> https://www.github.com/coralblocks/CoralRing
>
> For our particular systems (mostly financial low latency systems) it
> is important not to create any garbage (temp discarded instances) when
> receiving a message.
>
> We encountered an issue when copying from native memory straight into
> a direct ByteBuffer using the FFM API.
>
> 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.
>
> 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?
>
> Maybe there is already a way and we are just unaware how to do it.
>
> 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.
>
> Thanks and let me know if you need any more details about this and/or
> if I can help with anything.
>
> All the best,
>
> -Sergio
>
> // With sun.misc.Unsafe:
> @Override
> public void getByteBuffer(long address, ByteBuffer dst, int len) {
> if (!dst.isDirect()) {
> throw new RuntimeException("getByteBuffer can only take a
> direct byte buffer!");
> }
> try {
> long dstAddress = (long) addressField.get(dst); // get the
> memory address of this ByteBuffer
> dstAddress += dst.position(); // adjust the address for the
> ByteBuffer current position
> unsafe.copyMemory(address, dstAddress, len); // copy over
> dst.position(dst.position() + len); // adjust the ByteBuffer
> position to reflect the copy operation
> } catch(Exception e) {
> throw new RuntimeException(e);
> }
> }
>
> // With FFM API:
> @Override
> public void getByteBuffer(long address, ByteBuffer dst, int len) {
> if (!dst.isDirect()) {
> throw new RuntimeException("getByteBuffer can only take a
> direct byte buffer!");
> }
>
> long offset = address - this.address; // offset in our 'segment'
>
> try (Arena arena = Arena.ofConfined()) { // <==== probably
> creating a temp object here too
> // Wrap the destination ByteBuffer in a temporary segment
> // This segment's data starts at dst.position()
> MemorySegment dstSegment = MemorySegment.ofBuffer(dst, arena);
> // <====== temp memory segment object
>
> // Copy from 'segment' at 'offset' → dstSegment at offset 0 →
> length = 'len'
> dstSegment.copyFrom(this.segment, offset, 0, len);
> }
> dst.position(dst.position() + len);
> }
>
>
>
>
>
More information about the panama-dev
mailing list