我开发了一个Android应用程序,现在应用程序看起来运行良好,你想要宣布胜利并发布App,但你知道其中肯定存在一些内存和资源泄漏问题;而且在Android上只有16MB的堆空间,很容易在Android应用程序中出现泄漏问题。
我一直在寻找解决方法,目前只能找到关于“hprof”和“traceview”的信息,但这两种工具都没有得到太多好评。
您是否遇到过其他工具或方法,并且能够分享一些在OS项目中使用的经验?
我开发了一个Android应用程序,现在应用程序看起来运行良好,你想要宣布胜利并发布App,但你知道其中肯定存在一些内存和资源泄漏问题;而且在Android上只有16MB的堆空间,很容易在Android应用程序中出现泄漏问题。
我一直在寻找解决方法,目前只能找到关于“hprof”和“traceview”的信息,但这两种工具都没有得到太多好评。
您是否遇到过其他工具或方法,并且能够分享一些在OS项目中使用的经验?
主要适用于未来的Google旅行者:
大多数Java工具不幸地不能胜任此任务,因为它们只分析JVM堆。然而,每个Android应用程序也有本机堆,这也必须适合约16MB的限制。通常用于位图数据,例如。因此,即使您的JVM堆大小在3MB左右,如果使用了大量可绘制对象,您很容易遇到内存不足错误。
@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();
}
}
我希望有更加有原则的方法来释放这些资源。
2011年Google I/O关于Android内存管理的精彩演讲,以及内存分析工具和技术的详细介绍:
http://www.youtube.com/watch?v=_CruQY55HOk
Valgrind已被移植到Android(由Mozilla赞助)。请参见Valgrind on Android - Current Status和Support Running Valgrind for Android on ARM(评论67)。
好的,这些是与Android使用的独特格式相连接的工具..我认为你可能对使用的基础测试代码框架不满意..
你尝试过使用Android Mock Framework模拟测试代码区域吗?