什么 Android 工具和方法最有效地发现内存/资源泄漏?

我已经开发了一个 Android 应用程序,而且我正处于一个手机应用程序开发的关键时刻,似乎一切都运行良好,你想要宣布胜利和船舶,但是你知道只需要有一些内存和资源泄漏在那里; 在 Android 上只有16mb 的堆,而且显然在 Android 应用程序中很容易泄漏。

我一直在四处寻找,到目前为止只能找到关于“ hprof”和“ traceview”的信息,两者都没有得到很多好评。

在操作系统项目中,您遇到过或开发过哪些工具或方法,并愿意分享它们?

94869 次浏览

嗯,这些工具与 Android 使用的独特格式挂钩。.我认为您可能不满意的是正在使用的底层测试代码框架。.

您是否尝试过使用 Android 模拟框架模拟测试代码区域?

获取 Eclipse 内存分析器(http://www.eclipse.org/mat/) 检查 http://kohlerm.blogspot.com/2010/02/android-memory-usage-analysis-slides.html 还有一个 http://kohlerm.blogspot.com/search/label/memory

主要针对来自未来的谷歌旅行者:

不幸的是,大多数 Java 工具都不适合这个任务,因为它们只分析 JVM-Heap。不过,每个 Android 应用程序都有一个本机堆,它也必须满足 ~ 16MB 的限制。例如,它通常用于位图数据。因此,如果您使用了大量的绘图工具,那么即使您的 JVM-Heap 大约是3 MB,您也可以很容易地遇到内存不足的错误。

瓦尔格恩已经被移植到 Android (由 Mozilla 赞助) ,请参阅 安卓系统的现状支持在 ARM 平台上运行 Android 系统(评论67)。

关于 Android 内存管理的 Google I/O 演讲(2011) ,以及关于内存分析的工具 + 技术的细节:
Http://www.youtube.com/watch?v=_cruqy55hok

来自@hp 的答案。如果你只是使用位图背景,android 工作得很好,但是,在我的例子中,我有一个 BaseAdapter,它为 GridView提供了一组 ImageView。我按照建议修改了 unbindDrawables()方法,以便条件是:

if (view instanceof ViewGroup && !(view instanceof AdapterView)) {
...
}

但问题是递归方法从来不处理 AdapterView的子代。为了解决这个问题,我采取了以下措施:

if (view instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) view;
for (int i = 0; i < viewGroup.getChildCount(); i++)
unbindDrawables(viewGroup.getChildAt(i));


if (!(view instanceof AdapterView))
viewGroup.removeAllViews();
}

这样 AdapterView的子元素仍然会被处理——这个方法不会尝试删除所有的子元素(这是不受支持的)。

但是这并不能完全解决问题,因为 ImageView管理的位图不是它们的背景。因此,我添加了以下内容。这并不理想,但很有效:

if (view instanceof ImageView) {
ImageView imageView = (ImageView) view;
imageView.setImageBitmap(null);
}

总体而言,unbindDrawables()方法是:

private void unbindDrawables(View view) {
if (view.getBackground() != null)
view.getBackground().setCallback(null);


if (view instanceof ImageView) {
ImageView imageView = (ImageView) view;
imageView.setImageBitmap(null);
} else if (view instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) view;
for (int i = 0; i < viewGroup.getChildCount(); i++)
unbindDrawables(viewGroup.getChildAt(i));


if (!(view instanceof AdapterView))
viewGroup.removeAllViews();
}
}

我希望有一个更有原则的方法来释放这些资源。