【发布时间】: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$AttachInfo 的mScrollContainers 字段。问题是,我一开始不知道我的观点是如何进入那里的,所以我不知道如何堵住这个漏洞。
我该如何解决这个内存泄漏?或者至少,这个引用链是如何构建的,ViewRoot、AttachInfo 和 mScrollContainers 是什么?
我将尝试将其隔离为一个简单的测试用例并很快在此处发布代码,但我希望这足以让对话开始。
【问题讨论】:
-
你能告诉我你正在使用的图片的最大尺寸吗?
-
每个联系人图像为 32x32。对于我的示例数据,每个“页面”包含 10 个联系人,共有 7 个页面。我正在使用类似于Fedor's lazylist 的 ImageLoader,源图像每个大约为 37x37。
-
现在遇到了同样的问题。
-
我们也遇到过这个问题。还有一个事实是,即使 Gallery 是一个 AdapterView,它也永远不会将任何 convertView 传递给非 null 的 getView(),从而阻碍了有效的 View 重用。
标签: android out-of-memory