1

My app is composed of one fragmented activity and one service. Also a few receivers, connection to in-app billing (activity only) and a few other things. I'm also using app-compat-v7 for fragments and action bar.

When I look at the app under running apps activity (just the service is running), it reports a whopping 27 MB. Memory analyzer shows that those are pretty much contained in resource cache: bitmaps, strings, reflection data, DexCache, etc. Note that service itself pretty much MAYBE needs a string or two plus a couple of bitmaps for notification and widget, but definitely not that much.

The service with all its classes, notifications and widgets takes only 120KB while the rest takes 27MB. The package itself is 1.4MB without ProGuard.

I have searched repeatedly for a good solution, but nothing comes up that would help me with this.

How can I make my service consume less memory?

velis
  • 8,747
  • 4
  • 44
  • 64
  • You could set up the service to run in an [isolated process](http://developer.android.com/training/articles/memory.html#MultipleProcesses). – corsair992 Jan 21 '15 at 04:32
  • Yes, but does that significantly reduce memory usage as per above scenario? As I see it, the resources would still end up preloaded and memory usage pretty much the same. – velis Jan 21 '15 at 07:50
  • It will reduce the memory that is consumed by the service process, while the UI process will be managed separately instead of remaining bound to the service (and thus kept around by the system even when the app is in the background). If you want to reduce the overall memory of your app, then take a look at the other tips and advice provided in that link. – corsair992 Jan 21 '15 at 07:55
  • OK, I suppose it's pretty easy to check service memory usage by running it in separate process. If it turns out successful, I can worry about complexities of this solution for UI binding later. I will give it a go and see where it takes me. – velis Jan 21 '15 at 08:00
  • Separating service into subprocess reduces service's memory usage by 2MB (to 25MB), but at the same time introduces additional UI process with duplicated size. This is not the way to go, it seems. – velis Jan 21 '15 at 16:16
  • Hmm, then it looks like you have some shared/static memory that is accessible to both processes. As mentioned in the article, these will be replicated in both processes: "Additionally, when running more than one process, it's more important than ever that you keep your code as lean as possible, because any unnecessary RAM overhead for common implementations are now replicated in each process." – corsair992 Jan 22 '15 at 00:47
  • Definitely. Service also uses graphic resources in order to compose the notification. It seems Android is pretty aggressive when it comes to caching. As soon as any resource of a given type is accessed, all are pre-loaded. – velis Jan 22 '15 at 09:20
  • Hmm, interesting. I can't reproduce this behavior of all the drawables being cached upon loading only one in a Lollipop emulator. – corsair992 Jan 22 '15 at 10:10
  • Yes, same here: in 5.0 emulator, RAM usage is 9-12MB while on the actual ROM it's 27MB. Mostly due to images. – velis Jan 22 '15 at 12:51
  • What are you referring to by "actual ROM"? Which device and OS version? – corsair992 Jan 22 '15 at 13:17
  • HTC One M7. LiquidSmooth 5.0.2. – velis Jan 22 '15 at 13:36
  • 1
    While searching around for information on this issue, I came across the following post, which might explain what's going on: http://stackoverflow.com/questions/9653457/locating-and-remedying-cause-of-large-heap-size – corsair992 Jan 22 '15 at 17:24
  • Thanks for that find, it's exactly my problem. I have no idea how some manage to make services that take less RAM. Maybe it's appcompat v7 that actually messes me up so much? – velis Jan 23 '15 at 01:14
  • It seems from the accepted answer to that question that these are system drawable resources that are preloaded on every process. This might account for the discrepancy between emulator and device memory usage, as the resources can be defined by the vendor. To confirm, try to run an empty process with just a service running on your device, and see how much memory that consumes. – corsair992 Jan 23 '15 at 03:54
  • Aggreed. Done that. It's 8MB. Maybe there are triggers for this preloading, such as retrieving resources. I should probably try to debug everything from the start and see how RAM usage raises with service startup and object instantiation. That might provide a clue or two? – velis Jan 23 '15 at 09:23
  • According to the post, the drawables are preloaded as part of Zygote's initialization process, in which case they should be present at the start. Is your memory being used up by the `sPreloadedDrawables` array as shown in that question? In any case, obviously you can only find out exactly what's going on through debugging, and taking out different parts of your resources/logic to find out where the culprit is. – corsair992 Jan 23 '15 at 10:01

0 Answers0