MemorySegment.ofByteBuffer(ByteBuffer.allocateDirect())
Michael Zucchi
notzed at gmail.com
Sat Feb 5 11:27:03 UTC 2022
Evening,
I'm seeing a direct ByteBuffer being freed while still used by a
MemorySegment.ofByteBuffer(). I'm apparently using foreign-jextract @
commit 6c3e90789b1a6590894f09c2027a7fcf9e23af06 (Fri Jan 28 11:01:26
2022) but it hasn't changed for months.
The docs for ofByteBuffer() explicitly state the backing buffer is
referenced.
/**
* Creates a new buffer memory segment that models the memory
associated with the given byte
* buffer. The segment starts relative to the buffer's position
(inclusive)
* and ends relative to the buffer's limit (exclusive).
* <p>
* If the buffer is {@link ByteBuffer#isReadOnly() read-only}, the
resulting segment will also be
* {@link ByteBuffer#isReadOnly() read-only}. The scope associated
with this segment can either be the
* {@linkplain ResourceScope#globalScope() global} resource scope,
in case the buffer has been created independently,
* or some other resource scope, in case the buffer has been
obtained using {@link #asByteBuffer()}.
* <p>
* The resulting memory segment keeps a reference to the backing
buffer, keeping it <em>reachable</em>.
*
* @param bb the byte buffer backing the buffer memory segment.
* @return a new buffer memory segment.
*/
But I don't see how it could be looking at
AbstractMemorySegmentImpl.ofBuffer(), it just creates the segment using
(long, long, int, scope)
public static AbstractMemorySegmentImpl ofBuffer(ByteBuffer bb) {
...
return new NativeMemorySegmentImpl(bbAddress + pos, size,
modes, bufferScope);
...
}
For what it's worth this is the code i'm using. IntArray is just a thin
wrapper over MemorySegment.
IntArray loadSPIRV(String name) throws IOException {
try (InputStream is = TestVulkan.class.getResourceAsStream(name)) {
ByteBuffer bb =
ByteBuffer.allocateDirect(8192).order(ByteOrder.nativeOrder());
int length = Channels.newChannel(is).read(bb);
bb.position(0);
bb.limit(length);
return IntArray.create(MemorySegment.ofByteBuffer(bb));
}
}
IntArray mandelbrot_cs;
void demo() throws Exception {
mandelbrot_cs = loadSPIRV("mandelbrot.bin");
... at some point later and before i use it it's junk, vulkan
crashes ...
}
If I keep a hard reference to 'bb' then it works fine indicating it's
probably getting gc'd otherwise.
ByteBuffer bb;
IntArray loadSPIRV(String name) throws IOException {
...
bb.position(0);
bb.limit(length);
this.bb = bb;
...
}
This version of loadSPIRV works fine:
IntArray loadSPIRV(String name) throws IOException {
try (InputStream is = TestVulkan.class.getResourceAsStream(name)) {
MemorySegment seg =
((SegmentAllocator)scope).allocateArray(Memory.INT, 2048);
int length = Channels.newChannel(is).read(seg.asByteBuffer());
return IntArray.create(seg.asSlice(0, length));
}
}
Regards,
!Z
More information about the panama-dev
mailing list