I’m checking my app for Memory Leaks/Usage and came across something weird that I’ve only seen so far in Android 1.6 and 2.1. After clicking around in the app a bit and I run “adb shell dumpsys meminfo” for my application, I see the following:
DUMP OF SERVICE meminfo:
Applications Memory Usage (kB):
Uptime: 34639912 Realtime: 153524709
** MEMINFO in pid 5778 [com.app.myapp] **
native dalvik other total
size: 14336 4679 N/A 19015
allocated: 13971 4139 N/A 18110
free: 280 540 N/A 820
(Pss): 2986 4181 13491 20658
(shared dirty): 972 3948 620 5540
(priv dirty): 2876 3224 10976 17076
Objects
Views: 545 ViewRoots: 4
AppContexts: 32 Activities: 31
Assets: 2 AssetManagers: 2
Local Binders: 43 Proxy Binders: 79
Death Recipients: 2
OpenSSL Sockets: 1
SQL
heap: 91 dbFiles: 0
numPagers: 4 inactivePageKB: 0
activePageKB: 0
Asset Allocations
zip:/data/app/com.app.myapp.apk:/resources.arsc: 119K
As you can see, nothing is getting deallocated/GC’d, the Activities are piling up, the AppContexts, etc. until the app just crashes with an OutOfMemoryError. This doesn’t happen on 2.2+.
Can anybody give me some insight into why this is happening? I have a feeling it’s either something simple, or it’s just something weird with my app, but I’m at a loss as to why this is happening.
FYI, I’ve reproduced this in a 1.6 and 2.1 emulator, as well as my G1 running 1.6. A recent crash report from a user also shows this, which they were running 2.1 on a Droid Eris. Let me know if any more details/code is needed to help with this.
##UPDATE##
Thanks to the info from momo, I was able to track down some memory leak issues, which drastically cut down on the amount of Activities/AppContexts that would show in the Objects list of meminfo.
The number is now down to around the number of actual activities that are in my application, so it seems that on older versions of Android, it will show the total amount of objects your app is consuming. On newer versions it won’t, though that could just be only the case on my test devices.
To get a clear picture on why Activities are held up, I normally use MAT and then look at Path to GC root from the Activity that get stuck.
I’ve a created a simple project which load simple TestActivity in order to illustrate the process. Below is the code for it:
Here are the steps:
You should see that your Activity is held by com.android.internal.policy.impl.PhoneWindow$DecorView and no one else. If this is the a case, you are ok and this Activity will be eventually reclaimed by GC.
Now I will do change my class to include a static variable that will hold its own instance:
And if I run the code hprof with the same steps, I now get the reference of the Activity is held by the ArrayList and not the com.android.internal.policy.impl.PhoneWindow$DecorView signifying that there is possibility of a leak if I don’t clean up the array
Now, you don’t have to do that for every Activity, what I would do just briefly run the app and then dump the HPROF. You would then again filter by package to get the snapshot of your application. In the initial Histogram, you should be suspicious for any Activity that has number of instances more than one after hitting GC button in DDMS and start investigating from there.
One more note, on my 2.1 phones, I couldn’t get the HPROF via DDMS, so I did it through the emulator following these steps:
Since the hprof is dalvik based, in order to use it with memory profiling tools you need to convert it first via hprof-conv available in the tools directory of your Android SDK installation