Reputation: 175
I know this may seem impossible to determine without actual code but please bear with me. I think it's possible to determine something from the symptoms.
I have a hierarchy browser where each level of a hierarchy is displayed by its own activity. If you examine too many branches of the hierarchy, it will throw an OutOfMemoryError
exception. This sounds like a memory leak but a casual look at the code doesn't reveal anything obvious so I want some clarification on some aspects of Java and Android before I do a more thorough investigation.
First, can I rely on unused activities to be garbage collected before OutOfMemoryError
is thrown? I would consider it to be odd behavior if this were not the case but it would explain everything I'm encountering.
Secondly, can the Dalvik garbage collector collect circular references? I don't think I have any but if it can't, I'll know to look for that in my code.
I know there are way to leak memory in Android applications by creating references to things from places that live for the life of the program but, again, I don't think I'm doing that. For example, I haven't created any UI controls programatically, nor have I passed the current activity as a Context
to anything.
Finally, I've never noticed this bug before recently and the only thing that's changed since it was first created is that the Android version was upgraded from some flavor Jelly Bean to KitKat.
Any help would be greatly appreciated. Thank you!
Upvotes: 0
Views: 520
Reputation: 2667
First, can I rely on unused activities to be garbage collected before OutOfMemoryError is thrown?
Despite the popular belief, the answer is no. You can fill memory with activities up to the error being thrown and Android will neither destroy any activities in the back stack nor collect these activities during GC.
There was an option for the system to finish activities in the back stack but it was disabled at 2011. Now Android will just kill the entire process if the system memory is low. Foreground application will most likely hit per-application heap limit because system avoids to kill it and there may be a plenty of free memory for others.
Why activities aren't GC'ed? All running activities are stored in the ActivityThread class (which performs all interaction with the system and handles activities' lifecycle events), so they aren't eligible for garbage collection. They are only removed from here after being destroyed.
Secondly, can the Dalvik garbage collector collect circular references?
Yes, it can, just like regular JVM's garbage collector. Otherwise it wouldn't be Java-compatible.
You can check where all memory goes by employing Memory Analyzer tool and other techniques. These tools can show you what objects are on heap and what prevents them from being collected.
I can suggest you to use Fragments whithin a single Activity instead of multiple Activities. Fragments have callbacks that can be used to free view hierarchy when fragment goes off scree (to back stack).
Upvotes: 1