views:

200

answers:

1

I'm writing an app that has a foreground service, content provider, and a Activity front end that binds to the service and gets back a List of objects using AIDL. The service does work and updates a database.

If I leave the activity open for 4-8+ hours, and go to the "Running Services" section under settings on the phone (Nexus One) an unusually large amount of memory being used is shown (~42MB).

I figure there is a leak. When I check the heap memory i get Heap size:~18MB, ~2MB allocated, ~16MB free. Analyzing the hprof in Eclipse MAT seems fine, which leads me to theorize that memory is leaking on the stack. Is this even possible? If it is, what can I do to stop or investigate the leak? Is the reported memory usage on the "Running Services" section of android even correct (I assume it is)?

Another note: I have been unable to reproduce this issue when the UI is not up (with only the service running)

A: 

I'm writing an app that has a foreground service, content provider, and a Activity front end that binds to the service and gets back a List of objects using AIDL.

If that's all just one application, get rid of the AIDL and get rid of the content provider. Or, at least, don't use them yourself -- those are for other applications to use. They add overhead that you do not need for stuff inside your own VM.

...which leads me to theorize that memory is leaking on the stack. Is this even possible?

Not really. The main application thread stack is trivially small. Other threads have stacks that could get a lot bigger, but I'll be surprised if you are chewing up 42MB that way.

If it is, what can I do to stop or investigate the leak?

Since you already did a "spike solution" of testing sans UI and determining that is OK, I'd slowly reintroduce the UI and see when you start getting the problem. One likely candidate problem area would be updating the activity from a background thread, so you might turn that off and see what happens.

Since your problem isn't in the heap itself, my guess is that your problem is tied to bitmaps or other things that have lots of off-heap RAM usage. The camera in your avatar is another hint in this direction. :-) Make sure you are recycle()-ing your bitmaps and such, and see if that helps any.

CommonsWare
The service is really the workhorse of the application, the activity is just a window to see what's going on. I was under the impression that the only way to really pass data back to the activity was to bind to the service and use AIDL and parcel the objects. If there's a better way can you let me know?I had suspected that images could be at fault early on and have fallen back to one tiled background png for testing that is ~40KB. So I don't think it's that. I have a few ui elements that use layer drawables (buttons, progress bars) I don't know how efficient those are off-heap.
Matt
I recently tried using the ScheduledExecutorService in leu of a Timer in the app, If I'm improperly closing it, could the thread pool be left out in memory indefinitely? I'm going to try reverting back to the Timer based solution tonight to see if that changes anything.
Matt
Thank you for responding btw, I was afraid no one would be able to help on this odd subject.
Matt
For losing the AIDL/marshalling overhead, check out the LocalService example on the Android Developers' site.
Christopher
If you are trying to do work whether or not the activity is around, I really do not recommend either `ScheduledExecutorService` nor `Timer`, because those would imply you are trying to run an everlasting service. http://www.androidguys.com/2009/09/09/diamonds-are-forever-services-are-not/ For that pattern, consider `AlarmManager` and an `IntentService`, such as: http://github.com/commonsguy/cwac-wakeful If the service is only in support of the activity, consider using `postDelayed()` on a `View` in the `Activity` and have that call into the service, rather than the other way around.
CommonsWare
Thanks for all the info. After reading the article and examples, some restructuring, and no longer using the ContentProvider the service is performing much better.
Matt