Search code examples
javacmemory-leaksjna

JNA free memory allocated by shared library


I have the following functions in my C API:

MyStruct *create();
void destroy(MyStruct **s);

I map them by JNA to:

Pointer create();
void destroy(Pointer p);

I have a class that loads the shared library and uses these functions:

class MyClass{

    private mySharedLibrary library;
    private Pointer p;

    public MyClass(){
       this.library = (MySharedLibrary)Native.loadLibrary("mylibrary", MySharedLibrary.class);
       this.p = library.create();
    }
}

I don't know when and how to call the destroy function... Or shouldn't I call it at all? There are no destructors in Java. Moreover, it get MyStrct** as an argument... What should I do?


Solution

  • Your class should provide an explicit destroy, which you then invoke using the try-with-resources pattern.

    If try-with-resources is not available to you, and for whatever reason do not use explicit cleanup, you can use a finalizer. While these are not guaranteed to be run, in most cases it's probably good enough.

    class MyClass {
        private Object finalizer = new Object {
            protected void finalize() {
                if (MyClass.this.p != null) {
                    MyClass.this.library.destroy(MyClass.this.p);
                    MyClass.this.p = null;
                }
            }
        }
    }
    

    Note that you should test extensively within your own use case, to ensure that memory gets reclaimed according to your needs.