GC在BitmapFactory.decodeStream()上过于活跃

时间:2015-09-21 17:44:31

标签: java android bitmap garbage-collection bitmapfactory

我有一个显示缩略图网格的应用。应用程序将输入流解码为每个缩略图BitmapFactory.decodeStream()的位图,以便显示它。

,当我向上/向下滚动足够快时,我注意到GC处于超级活动状态。

Systrace dump

我试图隔离问题并编写了一个简单的应用程序,我在循环中执行10000次decodeStream()调用,并注意到即使有足够的内存,GC仍然会被不断触发(即使我调用了bitmap.recycle()每次迭代后)。

RAM

问题:如何在执行BitmapFactory.decodeStream()时阻止GC过于活跃?

1 个答案:

答案 0 :(得分:2)

在Android中处理内存的一般方法与环境问题的咒语相同:减少,重用,回收。 "降低"意味着"请求更少" (例如,在inSampleSize上使用BitmapFactory.Options仅加载下采样图像)。 "回收"意味着"确保它可以尽快收集垃圾"。

但是,之前"回收"来了"重用"。 The Dalvik garbage collector is not a compacting or moving collector, so heap can become fragmented。如果您已经拥有了正确大小的分配,请重新使用它,而不是让它被收集,然后必须重新分配它。使用位图,这意味着在inBitmap上使用BitmapFactory.Options,或使用为您执行此操作的图像加载库。

  

它会在Android> = 5.0

上提供相同的提升

通常是的,虽然确切的影响可能会有所不同。

  

或对L进行的优化使得不必使用inBitmap(不值得增加复杂性)?

ART的垃圾收集器有各种改进。最重要的是它 是一个压缩或移动的收藏家,虽然只有当你的应用程序在后台时,这对你的情况没有多大帮助。

然而,对于大字节数组(或其他没有指向其中其他对象的指针的其他大对象),ART也有一个单独的堆区域。 ART可以更有效地收集它们,并且它们将减少堆碎片。

话虽如此,我仍然使用inBitmap。如果您的minSdkVersion为21岁以上,可能,您可以尝试跳过inBitmap并查看其进展情况。但是,如果您的minSdkVersion低于21,则无论如何都需要inBitmap,而且我只是全面使用该代码。