GrumpyRodriguez
GrumpyRodriguez

Reputation: 769

Java FFM: how to manually release a MemorySegment?

I'm reading the documentation for JDK 22 and I cannot find a way to release a native MemorySegment. According to the documentation the only way to create a MemorySegment is to use an Arena, unlike being able to use the MemorySegment.allocateNative(...) method that was available in JDK 16 and 17.

My requirement is to build a shared library from a jar using native image tool that comes with Graal. This library should expose a function which will allocate a chunk of native memory from Java and return its address (and size) to the caller of the library. This means that I need the native memory allocated by Java to stay around, and later released by a dedicated call to another function exposed from the Java code, passing the original address that was returned from the call to the first Java function.

The types of Arena in FFM as of JDK 22 make this difficult. MemorySegments allocated via the global arena are never deallocated. Assuming I use a shared Arena, I need the lifetime of the Arena I need to use to extend beyond the first function call to Java side, so it looks like my only option is to keep the Arena itself reachable, by putting it into some static HashTable<> with a random integer key, then use that key in the second call to my Java api to close the Arena.

Am I missing something or is this the only way I can release native segments allocated by an Arena via a dedicated call to a Java function?

Upvotes: 1

Views: 490

Answers (1)

Jorn Vernee
Jorn Vernee

Reputation: 33865

All memory segments allocate through an Arena are deallocated when the arena is closed. There is no way to deallocate just an individual memory segment allocated by an Arena, at least not using the standard arena implementations that come with the JDK.

As I see it you have several options:

  1. Let the caller of the library specify the arena in which the memory should be allocated. This allows the caller to choose the optimal arena for their use case as well.
  2. Instead of returning just the address and size, return a handle object that embeds the arena used for the allocation, with a close() method that closes the arena.
  3. Bind to the native malloc and free functions and use them to allocate/free memory instead of the Arena API.

Upvotes: 6

Related Questions