C ++ native library - who should release memory and how?

This is about Android. Situation:

C ++ library and Java shell classes plus native functions (JNIs) for working with C ++ classes from a library. If you need a C ++ object for regular Java code, it creates the corresponding java shell object, which creates a C ++ object through a built-in function and remembers the pointer to its own object in the "long" variable. In all subsequent actions, the shell gives this pointer to its own functions, etc.

Problem:

How to release all selected C ++ objects at the end? Currently, each wrapper class has a “finalize” method, where it calls its own function to free a C ++ object, but Android does not guarantee a call to “finalize”! On the other hand, usually the C ++ library does not know how many and what types of C ++ objects are allocated by java code.

What will happen to the remaining allocated memory when our Java application is terminated, will Android automatically unload the entire heap used from its own library when the OS unloads the library?

+4
source share
3 answers

At the end of the process life cycle, all process memory (both a bunch of Java and C ++) will be freed and restored by the system. One thing, however, shutting down Android activity does not necessarily end the process. I am not sure that there is a policy of completing the process.

On the other hand, relying on garbage collection and completing () sounds like a solid design to me. You state: "Android does not guarantee finalize() ." Do you have a link to this? The reason is that in the case of rejection of "when the object is released as part of the completion of the process ...", we are still good.

And if you are super paranoid, you can write your own shell malloc () / free () / realloc (), save a list of all selected objects and enter a cleanup function that goes through the list and frees them all. However, the contained Java objects may end in a strange state of zombies, where memory is freed from under them. This is a complex proposal that is very easy to make a mistake. Therefore, I still say - believe in the garbage collector. The absence of this would be ... alarming.

+3
source

Due to differences in paradigms, you need to include explicit destruction in your Java objects, which are implemented under the hood using C ++ resources. So, close() or another such method. The same problem is related to JNI, so the answers to these questions will apply to you:

Get Java to call my C ++ destructor (JNI)

As for the memory problem when closing, it is best, in my opinion, not to rely on this. If you get to a clean state, valgrind, etc., make sure you don't leak.

But from a technical point of view - since Android is based on Linux, I would assume that this is normal and will free up all memory when the process closes. Using this, you can make your program faster than explicitly freeing memory (only for experts who use other methods to ensure the program is correct, and they do not leak at run time).

+1
source

We use JNI and we had such a problem.

Actually, the problem was that we overloaded finalize () to do the cleanup. We solved our problems by removing our finalize () and creating clean () instead. This clean () function calls the JNI function, which performs the corresponding deletions (and just in case sets C ++ pointers to zero). We call clean () in the same way as in C ++ with deletion (for example, when a variable is out of scope).

It worked for us. Hope this works for you. Good luck

0
source

All Articles