I've been tracking down potential memory leaks in my Android application, and I've come across one that I'm not sure what to do with. First, I'll describe what I'm trying to do.
For what it's worth, I'm building for Eclair (2.1, API level 7) and testing on an HTC Incredible running Gingerbread (2.3.7, API level 10). From observing LogCat, I assume my application has a maximum heap size of about 32MB.
I am trying to build an address book wherein you have several pages of contacts. You navigate between pages by scrolling left and right, and you navigate through the current page by scrolling up and down. To accomplish this, I am using a Gallery whose adapter adapts a contact list into a ListView, whose adapter in turn adapts a single contact into a RelativeLayout.
Everything seems to be working fine, but I'm running out of native (external) memory really quickly when swiping through the gallery. I made an HPROF dump after swiping around the Gallery for awhile and pulled it into MAT. In the Histogram, I found that I had a few hundred of my contact RelativeLayouts which were held onto solely by my contact ListViews. Here's what I found when I looked at the [truncated] MAT merge_shortest_paths output of that ListView:
android.view.ViewRoot1ドル
+ this0ドル android.view.ViewRoot
+ mAttachInfo android.view.View$AttachInfo
+ mScrollContainers java.util.ArrayList
+ array java.lang.Object[303]
+ [110], [112], [114], [116], [118], ... com.example.LeakyListView
+ ...and so forth.
The only thing holding onto those leaked ListViews was this android.view.View$AttachInfo's mScrollContainers field. Problem is, I don't know how my views are getting in there in the first place, so I'm at a loss on how to plug this leak.
How do I solve this memory leak? Or at the very least, how did this reference chain get built and what is ViewRoot, AttachInfo, and mScrollContainers?
I'll try and isolate it to a simple test case and post code here soon, but I'm hoping this is enough to get the conversation started.
-
can u tell me max size of image you are using ?Hemant Menaria– Hemant Menaria2011年11月10日 06:01:05 +00:00Commented Nov 10, 2011 at 6:01
-
Each contact image is 32x32. For my sample data, each "page" contains 10 contacts and there are 7 pages. I'm using an ImageLoader similar to Fedor's lazylist and the source images are each about 37x37.Leo Accend– Leo Accend2011年11月10日 06:08:00 +00:00Commented Nov 10, 2011 at 6:08
-
Running into this exact same issue now.Jerry Brady– Jerry Brady2012年02月27日 17:10:59 +00:00Commented Feb 27, 2012 at 17:10
-
We've also run into this. And also the fact that even though Gallery is an AdapterView, it will never pass in any convertView to getView() which is non-null, impeding efficienct View reuse.P Varga– P Varga2012年05月22日 09:47:14 +00:00Commented May 22, 2012 at 9:47
1 Answer 1
You really, really should use ViewPager instead of Gallery for this kind of thing: http://android-developers.blogspot.com/2011/08/horizontal-view-swiping-with-viewpager.html
3 Comments
ViewPager a shot. This is exactly what I was looking for when I started implementing this feature. Can you explain why this leak is an inherent problem with using the Gallery and a ListView in this way?ViewPager and the leaks have all but vanished. I'm still seeing some problems when swiping really quickly across different pages, but I suspect this isn't the fault of the ViewPager but of the way I'm loading images. Thanks for the heads-up! Using Gallery felt like a hack, anyway.