【问题标题】:Android memory leak with ListView inside a Gallery画廊内 ListView 的 Android 内存泄漏
【发布时间】:2011-11-10 05:53:09
【问题描述】:

我一直在跟踪我的 Android 应用程序中潜在的内存泄漏,但我遇到了一个我不确定如何处理的问题。首先,我将描述我正在尝试做的事情。

对于它的价值,我正在为 Eclair(2.1,API 级别 7)构建并在运行 Gingerbread(2.3.7,API 级别 10)的 HTC Incredible 上进行测试。通过观察 LogCat,我假设我的应用程序的最大堆大小约为 32MB。

我正在尝试建立一个通讯录,其中您有几页联系人。您通过左右滚动在页面之间导航,通过上下滚动浏览当前页面。为此,我使用了Gallery,其适配器将联系人列表适配为ListView,其适配器又将单个联系人适配为RelativeLayout

一切似乎都运行良好,但在浏览图库时,我的本地(外部)内存真的很快用完了。在Gallery 上刷了一会儿之后,我做了一个 HPROF 转储,然后把它拉进了 MAT。在直方图中,我发现我有几百个联系人RelativeLayouts,这些联系人仅由我的联系人ListViews 持有。这是我在查看 ListView 的 [截断] MAT merge_shortest_paths 输出时发现的:

android.view.ViewRoot$1
+ this$0 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.

唯一保留那些泄露的ListViews 是android.view.View$AttachInfomScrollContainers 字段。问题是,我一开始不知道我的观点是如何进入那里的,所以我不知道如何堵住这个漏洞。

我该如何解决这个内存泄漏?或者至少,这个引用链是如何构建的,ViewRootAttachInfomScrollContainers 是什么?

我将尝试将其隔离为一个简单的测试用例并很快在此处发布代码,但我希望这足以让对话开始。

【问题讨论】:

  • 你能告诉我你正在使用的图片的最大尺寸吗?
  • 每个联系人图像为 32x32。对于我的示例数据,每个“页面”包含 10 个联系人,共有 7 个页面。我正在使用类似于Fedor's lazylist 的 ImageLoader,源图像每个大约为 37x37。
  • 现在遇到了同样的问题。
  • 我们也遇到过这个问题。还有一个事实是,即使 Gallery 是一个 AdapterView,它也永远不会将任何 convertView 传递给非 null 的 getView(),从而阻碍了有效的 View 重用。

标签: android out-of-memory


【解决方案1】:

你真的,真的应该使用 ViewPager 而不是 Gallery 来处理这种事情:http://android-developers.blogspot.com/2011/08/horizontal-view-swiping-with-viewpager.html

【讨论】:

  • 我要试一试ViewPager。这正是我开始实现此功能时所寻找的。你能解释一下为什么这种泄漏是以这种方式使用GalleryListView 的固有问题吗?
  • 我改用ViewPager,泄漏几乎消失了。在不同页面上快速滑动时,我仍然看到一些问题,但我怀疑这不是ViewPager 的错,而是我加载图像的方式。感谢您的提醒!无论如何,使用Gallery 感觉就像是一种黑客攻击。
  • Gallery 并不是为了容纳像 ListView 这样可滚动的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-18
  • 2011-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多