哪些 Android 工具和方法最适合查找内存/资源泄漏? [关闭]
Posted
技术标签:
【中文标题】哪些 Android 工具和方法最适合查找内存/资源泄漏? [关闭]【英文标题】:What Android tools and methods work best to find memory/resource leaks? [closed] 【发布时间】:2010-11-11 22:36:25 【问题描述】:我已经开发了一个 android 应用程序,我正处于一个手机应用程序开发阶段,一切似乎都运行良好,你想宣布胜利并发布,但你知道只需要一些记忆以及那里的资源泄漏; Android 上只有 16mb 的堆空间,而且在 Android 应用中很容易泄漏。
我一直在四处寻找,到目前为止只能挖掘关于“hprof”和“traceview”的信息,但都没有得到很多好评。
您在 OS 项目中遇到或开发并愿意分享哪些工具或方法?
【问题讨论】:
我可以投票让 Р̀СТȢѸ́ФХѾЦЧШЩЪЫЬѢѤЮѦѪѨѬѠѺѮѰѲѴ 将他的名字改成人类可读的名字。 如果我们从问题标题中删除“Android 工具”一词,是否可以重新打开此问题?这里找到的答案对于解决我的内存泄漏问题非常有用 好的,所以我有一个用户经常在活动之间切换,这意味着他们可能在 20 秒内切换了 15 个活动。这可能是导致内存不足错误的原因吗?我应该怎么做才能修复它?谢谢! 由于问题已关闭,因此无法提供此回复,但我建议您查看Leak Canary。只需使用您的应用程序,打开和关闭活动,然后让图书馆完成它的工作。它甚至会告诉您泄漏发生的位置。泄漏发生后,只需给泄漏分析仪一些时间来完成工作 - 通常需要大约 2 分钟或更长时间才能找到泄漏源。之后,它会在应用程序内整齐地呈现给您。无需额外工具! 【参考方案1】:我发现开发 Android 应用程序的最常见错误之一是“java.lang.OutOfMemoryError: Bitmap Size Exceeds VM Budget”错误。我在更改方向后使用大量位图的活动上经常发现此错误:活动被销毁,再次创建,布局从 XML 中“膨胀”,消耗了位图可用的 VM 内存。
前一个活动布局上的位图没有被垃圾收集器正确释放,因为它们交叉引用了它们的活动。经过多次实验,我找到了一个非常好的解决这个问题的方法。
首先,在 XML 布局的父视图上设置“id”属性:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:id="@+id/RootView"
>
...
然后,在 Activity 的 onDestroy() 方法上,调用 unbindDrawables() 方法,将引用传递给父 View,然后执行 System.gc()
@Override
protected void onDestroy()
super.onDestroy();
unbindDrawables(findViewById(R.id.RootView));
System.gc();
private void unbindDrawables(View view)
if (view.getBackground() != null)
view.getBackground().setCallback(null);
if (view instanceof ViewGroup)
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++)
unbindDrawables(((ViewGroup) view).getChildAt(i));
((ViewGroup) view).removeAllViews();
这个 unbindDrawables() 方法递归地探索视图树并且:
-
移除所有背景可绘制对象的回调
删除每个视图组中的子项
【讨论】:
解决一个常见问题的好方法。 这不适用于 AdapterView 的子类(ListView、GridView 等)。 @Arjun 是的..它不适用于 AdapterView 子类。为此,您需要处理异常。休息它工作正常。这就是我在我的代码中使用的,它工作正常。希望这会有所帮助。 @hp.android 通过“在异常中处理这个”你有一个例子来说明它的样子吗?我问是因为我的PageAdapter
中有几页图像,我被这个错误解决了:(
@Jackson 只需更改条件: if (view instanceof ViewGroup && !(view instanceof AdapterView)) 这将摆脱您为 Adapter 获得的异常【参考方案2】:
如果您只使用位图背景,@hp.android 的答案效果很好,但在我的情况下,我有一个 BaseAdapter
为 GridView
提供一组 ImageView
s。我按照建议修改了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
s 管理的位图不是他们的背景。因此,我添加了以下内容。这并不理想,但它有效:
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();
我希望有一种更有原则的方法来释放这些资源。
【讨论】:
【参考方案3】:关于 Android 内存管理的 Google I/O 演讲(2011 年),以及有关内存分析工具和技术的详细信息:http://www.youtube.com/watch?v=_CruQY55HOk
【讨论】:
或对应博文:android-developers.blogspot.com/2011/03/… 好的,所以我有一个用户经常在活动之间切换,这意味着他们可能在 20 秒内切换了 15 个活动。这可能是内存不足错误的原因吗?我应该怎么做才能修复它?谢谢!'【参考方案4】:Valgrind 已移植到 Android(由 Mozilla 赞助)。请参阅 Valgrind on Android — Current Status 和 Support Running Valgrind for Android on ARM(评论 67)。
【讨论】:
这需要构建自定义 rom。【参考方案5】:主要面向来自未来的 Google 旅行者:
不幸的是,大多数 java 工具都不适合这项任务,因为它们只分析 JVM-Heap。但是,每个 Android 应用程序也有一个本机堆,它也必须在 ~16 MB 的限制内。例如,它通常用于位图数据。因此,如果您使用大量可绘制对象,即使您的 JVM 堆在 3 MB 左右,您也很容易遇到内存不足错误。
【讨论】:
启动 Android 3.0 (honeycomb) 可绘制对象存储在堆中 @Timo 那么您将使用什么来检测本机堆中的泄漏? 测试,大量测试。问题是,由于内存共享和其他优化技术,您甚至无法真正知道您的应用程序正在使用多少内存。您可以使用常用的 shell 命令获取内存读数,但这些都是非常非常粗略的估计。【参考方案6】:获取 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
【讨论】:
【参考方案7】:嗯,这些是与 Android 使用的独特格式挂钩的工具..我认为您可能不满意的是正在使用的底层测试代码框架..
您是否尝试过使用 Android Mock 框架模拟测试代码区域?
【讨论】:
不多,测试这种性质与其说是记录应用程序运行时实际发生的事情,我真正需要的是资源/内存泄漏分析工具以上是关于哪些 Android 工具和方法最适合查找内存/资源泄漏? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章