Mergeadapter内存泄漏?

时间:2012-12-05 15:19:47

标签: android memory-leaks

我正在调查我们的应用程序中的outofmemoryerror bugreport。

我们的应用程序显示了一个列表视图,其中包含应用程序图标作为列表视图项目的一部分。

当使用标准baseadapter填充此列表视图时,会发现当包含它们的视图不在视线范围内时,应用程序不会保留在drawable中。

这也是使用弱引用进行测试的:

 public Drawable getIcon() {
        Log.v("AppResult", "getIcon()");
        Drawable icon = appInfo.loadIcon(pm);       
        leakTester.add(new WeakReference<Drawable>(icon));
        ArrayList<WeakReference<Drawable>> copy = new ArrayList<WeakReference<Drawable>>(leakTester); 
        for (WeakReference<Drawable> oldIcon: leakTester)
        {
            if (oldIcon.get() == null)
            {
                Log.v("AppResult", "iconRecycled");
                copy.remove(oldIcon);
            }
        }
        leakTester = copy;
        return icon;
    }

滚动浏览正常的baseadapter驱动的listview时记录:

12-05 16:17:57.450: V/AppResult(24890): getIcon()
12-05 16:17:57.450: V/AppResult(24890): iconRecycled
12-05 16:17:57.510: V/AppResult(24890): getIcon()
12-05 16:17:57.520: V/AppResult(24890): iconRecycled
12-05 16:17:57.580: V/AppResult(24890): getIcon()
12-05 16:17:57.590: V/AppResult(24890): iconRecycled
12-05 16:17:57.730: V/AppResult(24890): getIcon()
12-05 16:17:57.730: V/AppResult(24890): iconRecycled
12-05 16:17:58.510: V/AppResult(24890): getIcon()
12-05 16:17:58.510: V/AppResult(24890): iconRecycled
12-05 16:17:58.570: V/AppResult(24890): getIcon()
12-05 16:17:58.570: V/AppResult(24890): iconRecycled
12-05 16:17:58.650: V/AppResult(24890): getIcon()

然而,当我使用mergeAdapter时,它会填充交替的头文本视图和基本适应器,就像之前使用的那样,我得到的消息很少iconRecycled。即使这些适配器在可用时也使用了recycleview。 (在滚动完整列表后,该应用程序的使用量为35MB!在其他活动中,该应用程序的使用率为12MB)。

12-05 16:15:04.800: V/AppResult(24890): getIcon()
12-05 16:15:04.860: D/dalvikvm(24890): GC_FOR_ALLOC freed 34K, 1% free 35857K/36167K, paused 26ms
12-05 16:15:04.860: V/AppResult(24890): getIcon()
12-05 16:15:04.910: V/AppResult(24890): getIcon()
12-05 16:15:04.910: V/AppResult(24890): getIcon()
12-05 16:15:04.910: V/AppResult(24890): iconRecycled
12-05 16:15:04.910: V/AppResult(24890): iconRecycled
12-05 16:15:04.950: V/AppResult(24890): getIcon()
12-05 16:15:04.950: V/AppResult(24890): getIcon()
12-05 16:15:04.950: V/AppResult(24890): getIcon()
12-05 16:15:13.260: V/AppResult(24890): getIcon()
12-05 16:15:13.430: V/AppResult(24890): getIcon()
12-05 16:15:13.590: V/AppResult(24890): getIcon()
12-05 16:15:14.300: V/AppResult(24890): getIcon()
12-05 16:15:14.370: V/AppResult(24890): getIcon()
12-05 16:15:14.440: V/AppResult(24890): getIcon()

这是我的实施中的错误吗?看起来mergeadapter以某种方式不再释放不在视图中的视图。这是对的吗?

修改

我通过MAT运行它,这就是结果:

java.util.ArrayList[32] @ 0x413beb88  144 19.833.288 
  \mScrapViews android.widget.AbsListView$RecycleBin @ 0x4129bd9040 19.833.496 
    .\mRecycler android.widget.ListView @ 0x412c5db8  896 23.635.384 
      ..+mFocusedView, mRealFocusedView android.view.ViewRootImpl @ 0x4133fae8 440 1.776 
        ..|+this$0 android.view.ViewRootImpl$2 @ 0x4136f540 Native Stack 16 16 
        ..|+[1] android.view.ViewRootImpl[2] @ 0x41340930 » 24 24 
        ..|+this$0 android.view.ViewRootImpl$AccessibilityInteractionConnectionManager @ 0x413157e8 » 16 16 
        ..|\Total: 3 entries       
      ..+mServedView, mNextServedView android.view.inputmethod.InputMethodManager @ 0x413511f8 » 104 368 
      ..+listview com.denper.addonsdetector.ui.InstallDateLister @ 0x412d8bd8 »

1 个答案:

答案 0 :(得分:0)

  

看起来mergeadapter以某种方式不再释放不在视图中的视图。这是对的吗?

如果“视图”是指“交替标题文字视图”,那么当然MergeAdapter“不会释放不再在视图中的视图” - 如果MergeAdapter发布了它们,当用户向后滚动时,MergeAdapter无法显示它们,因为一旦释放,它就无法再将View恢复。

如果“视图”中的意思是“像以前使用的那样的基础适应器”的内容,那么MergeAdapter从不首先保留那些View,因此不能持有它们。但是,getCount()等方法的增加值可能会导致ListView中的缓存更改。