我有位图内存泄漏导致内存不足。我在 Android 5.0(三星 S5)上运行了测试。我已经使用 Android Studio (1.5.1 + 2.0.0 Preview 7) 调查了这个问题。 HPROF 内存转储显示有多个 byte[] 与我暂时使用的特定巨大位图完全对应。如果我确保保留对位图的引用,那么 Android Studio 会向我显示一个 11MB 主尺寸的位图和一个 11MB 浅尺寸的字节[]。如果我不保留对位图的引用,那么一些位图将被垃圾收集,而一些位图最终会成为没有传入引用(即没有父级)的 byte[],如图所示。
我已经对我的应用程序进行了足够的测试,可以合理地确信这个 11MB byte[] 是我在内存中的大约 2891x1000x4 位图。一些较小的位图也会泄漏,并且显示时没有传入引用。
上面的位图是在子活动中分配的。如果我返回父活动(在同一进程中,因此是 dalvikVM)并强制执行 2x GC,则内存将被释放。多次手动 GC 在退出子活动之前不会释放内存。
它似乎与我是否运行 bitmap.recycle() 无关。如果我只是站在应用程序中的同一位置并运行从同一视图生成巨大位图的代码,这种情况很少发生。如果我在应用程序中移动并从不同视图生成位图,则出现的频率会更高,例如从 50% 泄漏到 10% 泄漏。
- 这是安卓的bug吗?
- 我是否以某种方式错误地使用了位图并且 Android studio 无法向我显示正确的内存视图?
- 我的理解是否正确,如果下面的参考树中没有父级(参见图片),那么内存应该由垃圾收集器释放(因此它是 Android Bug 或 studio bug 或 hprof dump-bug?)
我找到了泄漏的解决方案,通过 Android Studio 报告未引用的 byte[] 仍然是一个谜。
看来我所做的 ImageView
imageView.setImageBitmap(bitmap)
将阻止对 byte[] 底层位图进行 GC。 bitmap.recycle() 没有帮助,unbinddrawables() 也没有帮助,正如许多地方所写的那样
if (imageView.getBackground() != null) {
imageView.getBackground().setCallback(null);
}
setImageBackground(imageView, null);
imageView.setImageBitmap(null);
imageView.setImageDrawable(null);
当我从 viewhiearchy 中删除视图并删除我自己对该视图的所有引用时,byte[] 被 GC 处理,泄漏消失了。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)