Let's consider below special case:
Case description:
Java App call jni then native mediaserver to create a instance. This native instance will use about 40M memory.
Java App didn't release this instance but release it in finalize (GC).
If many such instance created by Java App, then the memory in Java is increase but not too much, native instance will occupy N*40M memory, many memory will be consumed by native process if GC not happen in time.
Questions:
For this case, when will GC triggered by Java? Will GC consider the native memory increase then call GC automatically?
Should we call System.gc() in Java layer to release native memory? Someone seems don't agree to call System.gc() by application.
What's best solution to resolve such memory shortage!
Actually, GC is a java layer concept, for native code, no such concept I guess.
Related
Unlike JVMs, which are simple stack-based machines, the Dalvik VM uses a register-based — which requires fewer instructions, avoids unnecessary memory access — resulting in better performance code.
But how does Dalvik manage thread stacks? Does it create a stack for a thread?
Yes. The "registers" are just locations on the call stack. When you call into a method, it allocates however much space is needed on the stack to hold the "registers" for the method being called.
My app is consuming a lot of memory
I have used the following app to measure my app memory consumption
https://play.google.com/store/apps/details?id=mem.usage&hl=en
can any one tell me how can I optimize the memory used by my app?
1) you can use LeakCanry for optimize memory. leakCanry will give you report for each individual leaks or when multiple instance of an activity will be on stack.
here is more info and integration guide https://github.com/square/leakcanary
2) you can check android studio memory monitor for your app's memory use. from that graph you can check when GC is being called and which activity or function is taking more memory so you can optimize through it.
more info regarding this http://developer.android.com/tools/performance/memory-monitor/index.html
3) i have gone through udacity tutorial and videos. you can see how to improving rendering for your layouts
Need to reduce unnecessary views.
dont apply unnecessary background.
more stuff https://www.udacity.com/course/android-performance--ud825
4) one more important thing use ApplicationContext where you can use it because Activity context keeps in stack and wont be eligible for GC until that context related task is being finished.
https://developer.android.com/tools/performance/comparison.html
Start with running Memory Profiler Tool to see what is the causes that leak/consume much memory in your app.
We have a large app that's always running into the dread method count limit. I've been asked to come up with a way to let it do much more, including supporting plugins. Looking for ways to unload code, I ran across JNI Tips which says
Classes are only unloaded if all classes associated with a ClassLoader
can be garbage collected, which is rare but will not be impossible in
Android.
This did seem to imply that a plugin can be unloaded if you, say,
use a new DexClassLoader for each .jar file,
only ever refer to the plugin through an interface reference, and
null-out any copies of that interface reference when done.
So, I created a test case:
I created a couple of trivial plugins, using a unique loader for each.
I created a ReferenceQueue<ClassLoader> and created weak references to my two loaders, using that queue; I created/started a thread that loops indefinitely, doing a queue .remove() and reporting.
I similarly created a ReferenceQueue<Class<?>> and created weak references to each plugin's getClass() using the queue; I created/started another thread monitoring the class reference queue.
I create a thousand 1000x1000xARGB_8888 bitmaps to thoroughly force gc.
My monitoring threads seem to work - I saw loader2 get gc-ed when I used loader1 to load both plugins by mistake ;-) - but otherwise my threads stay silent, even on 4.3. Am I maybe missing something obvious in this test case, or is it still the case that the
Dalvik VM doesn't currently unload classes
as Google employee fadden says in Android: When do classes get unloaded by the system?
The Dalvik VM still doesn't unload classes. The JNI Tips page is encouraging good behavior so your app doesn't break if the VM starts unloading classes someday.
I have developed a small application which used a shared library. When i run that android application in my device heap memory is increasing rapidly. I try to reduce that using gc() but that is not work for me. At one time am getting a message like Low memory no more background process and my app quit. How could i resolve this?
You have not only to use GC, but also drop references to the objects you do not need anymore - GC will not reclaim referenced objects. You also have towatch carefully what JNI library does and also take necessary precautions in case it allocated memory of start threads.
More detailed answer is not posssible until you say what you are using and post the sources
This is about Android. The situation:
C++ library and java wrapper classes plus native functions (JNI) for working with C++ classes from the library. When common java code needs C++ object, it creates corresponding java wrapper object which creates C++ object through native function and remembers the pointer to the native object in 'long' variable. In all next actions the wrapper gives this pointer to the native functions etc.
The problem:
How to release all allocated C++ objects at the end? Currently every wrapper class has 'finalize' method where it calls native function for releasing of the C++ object, but Android doesn't guarantee the calling of 'finalize'! At the other side, normally the C++ library has no idea how many and what types of C++ objects are allocated by java code.
What will happens with the remaining allocated memory when our java application terminates, will Android release automatically the whole heap, used from the native library, when the OS unloads the library?
At the end of the process lifetime, all process memory (both Java and C++ heap) will be freed and reclaimed by the system. One thing is though, Android activity closing does not necessarily end the process. I'm not sure what's the process shutdown policy there.
On the other hand, relying on the garbage collection and finalize() sounds like solid design to me. You claim - "Android does not guarantee finalize()". Do you have a cite for that? 'Cause if it comes with a disclaimer of "when the object is freed as a part of process shutdown...", then we're still good.
And if you're super-paranoid, you can write your own malloc()/free()/realloc() wrapper, store a list of all allocated objects, and introduce a cleanup function that walks the list and frees them all. The containing Java objects, however, might end in a weird zombie state where the memory has been freed from under them. This is a tricky proposition that is very easy to get wrong. So I'd still say - have faith in the garbage collector. Lack thereof would be... disturbing.
Due to the difference in paradigms, you have to incorporate explicit destruction into your Java objects that are implemented under the hood using C++ resources. So a close() or other such method. The same issue comes up with the JNI, so answers to those questions will apply to you:
Force Java to call my C++ destructor (JNI)
As for the memory issue on closing, it's generally best in my opinion to not rely on this. If you get to a clean state, valgrind and such can make sure you weren't leaking.
But from a technical standpoint--since Android is based on Linux, I'd imagine it does the usual thing and will free all the memory when the process closes. Taking advantage of that can make your program exit faster than explicitly freeing memory (for experts only who use other methods to ensure this maintains program correctness and they aren't leaking at runtime).
We are using JNIs and we had a problem like that
Actually, the problem resided in the fact that we were overloading finalize() to do the clean up. We solved our problems by removing our finalize() and creating a clean() instead. This clean() calls the JNI function that does the appropriate deletes (and set the C++ pointers to null, just in case). We call clean() just as you would in C++ with delete (e.g. when the variable goes out of scope).
That worked for us. I hope it works for you. Good luck!