DeepMedia logo
Open Source
Search...

Other versions of this page

Improve this page on GitHub

Search

Buffers

Definition

When dealing with memory and buffers, you may at some point need to pass them through the Native/JVM interface efficiently by reference, avoiding copies especially as their size grows.

Knee provides a built-in solution for this problem based on java.nio direct buffers and their native counterparts defined by the knee-runtime package. You can use:

  • A direct java.nio.ByteBuffer on the JVM and io.deepmedia.tools.knee.runtime.buffer.ByteBuffer on native;
  • A direct java.nio.DoubleBuffer on the JVM and io.deepmedia.tools.knee.runtime.buffer.DoubleBuffer on native;
  • A direct java.nio.FloatBuffer on the JVM and io.deepmedia.tools.knee.runtime.buffer.FloatBuffer on native;
  • A direct java.nio.IntBuffer on the JVM and io.deepmedia.tools.knee.runtime.buffer.IntBuffer on native;
  • A direct java.nio.LongBuffer on the JVM and io.deepmedia.tools.knee.runtime.buffer.LongBuffer on native.

Whenever such buffers are used as parameters or return types for Knee functions, the runtime will convert between the two.

Memory leaks

Native buffers are just thin wrappers around a CPointer. Should you choose to allocate such buffers on the native side (see examples), you must free them after use, using buffer.free().

⚠️

Natively allocated buffers are usable on the JVM only until the buffer.free() call

This requirement is lifted when buffers are allocated on the JVM side and passed down. In this case, buffers will keep a strong reference to the java.nio.ByteBuffer, so memory will be reclaimed only when all buffers (on both sides!) go out of scope and are garbage collected.

Examples

Allocate on JVM, pass down
kotlin
// JVM val buffer = java.nio.ByteBuffer.allocateDirect(1024) fillBuffer(buffer) // Native @Knee fun fillBuffer(buffer: io.deepmedia.tools.knee.runtime.buffer.ByteBuffer) { check(buffer.size == 1024) val rawPointer: CArrayPointer<ByteVar> = buffer.ptr // Fill rawPointer... }
Allocate natively, pass up
kotlin
// JVM useBuffer(1024) { buffer: java.nio.ByteBuffer -> check(buffer.capacity == 1024) // Use it... } // Native @Knee fun useBuffer(size: Int, block: (io.deepmedia.tools.knee.runtime.buffer.ByteBuffer) -> Unit) { val environment = currentJavaVirtualMachine.env!! val buffer = io.deepmedia.tools.knee.runtime.buffer.ByteBuffer(environment, size) try { block(buffer) } finally { buffer.free() } }

Subscribe to the DeepMedia Newsletter

The latest news about DeepMedia products, open source projects and software development at our company.

By clicking “Subscribe”, you agree that DeepMedia may use your email address to send you newsletters, including commercial communications, and to process your personal data for this purpose. You agree that DeepMedia may process said data using third-party services for this purpose in accordance with the DeepMedia Privacy Policy. You can revoke this consent at any time using the unsubscribe link included in each email or by writing at contact@deepmedia.io.