views:

252

answers:

1

I am finding that performance degrades after one or more screen rotations, and I presume that this is likely to be because an App's main Activity is destroyed and recreated each time the screen is rotated and that my app must be leaking memory when that happens.

I have read that, contrary to what one might expect, not all the objects created by an app's main Activity (or in classes called by that Activity) are destroyed when the activity is destroyed. Specifically, I think I have read (although I can't now find where) that if the View uses a large bitmap member object then the Activity's onDestroy() method should be over-ridden and the bitmap should be explicitly recycled.

Are there other objects that need to be destroyed or removed when the Activity is destroyed? What about Listeners? Is there a comprehensive tutorial or guide on this subject?

+4  A: 

Is there a comprehensive tutorial or guide on this subject?

Not really.

Are there other objects that need to be destroyed or removed when the Activity is destroyed? What about Listeners?

Bitmaps are unusual, in part because they use memory outside of the 16MB heap, if I understand the byzantine Android memory model correctly.

Beyond large bitmaps, the biggest thing you really need to worry about are things that prevent normal garbage collection from working. Anything that holds onto the activity, directly or indirectly, from a static context will keep the activity from being garbage collected. Examples include:

  • static data members on classes (e.g., you rig up your own listener framework with one of your services, so your service holds onto a listener which holds onto your activity)
  • threads (e.g., you manually fork a background thread and do not terminate it)
CommonsWare
Thanks for your prompt answer. Since I don't know how to create my own service or to fork a thread, I presume that neither of these are problems for me. One thing I don't understand is, given the basic principle that the GC will reclaim memory from an object when it goes out of scope, why this doesn't happen to a bitmap created within an Activity when that Activity ends. I feel that if I understood that I would have a better chance of identifying other things that might cause similar problems.
"One thing I don't understand is, given the basic principle that the GC will reclaim memory from an object when it goes out of scope, why this doesn't happen to a bitmap created within an Activity when that Activity ends" -- for starters, GC is not immediate. It happens asynchronously. For large memory blocks like bitmaps, that may be too late, so there is a mechanism for proactively hinting to Android that the bitmaps can be recycled (e.g., for use by your next Activity).
CommonsWare
Thanks for the explanation.
I have another large bitmap which is defined and used as a local variable within a method of one of my classes. I had been assuming that, since it is used purely locally, there would be no need to recycle it. However, bearing in mind your explanation of how GC works, I now wonder whether I need to recycle this bitmap too?
Large bitmaps require more care than would most local variables. I would try to proactively recycle it rather than just rely on garbage collection.
CommonsWare
OK. I've now added code to recycle the "temporary" bitmap as well. If the SysInfo graph in DDMS includes bitmaps as well as the heap, this change seems to have reduced the memory requirement, although there is still a small leak on each screen rotation which I must investigate.