Search code examples
javamemorymemory-leaksjava-native-interfacejna

Is there a memory leak issue with using JNA's Memory class?


I am in a position where I want to pass byte[] to a native method via JNA. All the examples I've found about this sort of thing either use a Memory instance or use a directly-allocated ByteBuffer and then get a Pointer from that.

However, when I read the docs they say that underlying native memory -- which as I understand it is allocated "off the books" outside of the JVM-managed heap -- these Java objects consume only get freed when the objects' finalize() method is called.

But when that finalizer gets called has nothing to do with when the objects go out of scope. They could hang around for a long time before the garbage collector actually finalizes them. So any native memory they've allocated will stay allocated for an arbitrarily-long time after they go out of scope. If they are holding on to a lot of memory and/or if there are lots of the objects it would seem to me you have an effective memory leak. Or least will have a steady-state memory consumption potentially a lot higher than it would seem to need to be. In other words, similar behavior to what's described in JNA/ByteBuffer not getting freed and causing C heap to run out of memory

Is there any way around this problem with JNA? Or will I need to give up on JNA for this and use JNI instead so that I can use JNIEnv::GetByteArrayElements() so there's no need for any "off the books" memory allocations that can persist arbitrarily long? Is it acceptable to subclass Memory in order to get access to the dispose() method and use that to free up the underlying native memory on my timeline instead of the GC's timeline? Or will that cause problems when the finalizer does run?


Solution

  • JNA provides Memory.disposeAll() and Memory.dispose() to explicitly free memory (the latter requires you to subclass Memory), so if you do ever encounter memory pressure for which regular GC is not sufficient, you have some additional control available.