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

GC is too active on BitmapFactory.decodeStream()

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

我注意到当我滚动 up/down 足够快时 GC 是否超级活跃,这使得滚动不稳定。



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

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

Android 中处理内存的一般方法与环境问题的口头禅相同:减少、重用、回收。 "Reduce" 表示 "request less"(例如,在 BitmapFactory.Options 上使用 inSampleSize 以仅加载下采样图像)。 "Recycle" 表示 "make sure it can get garbage-collected ASAP".

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

Will it give the same boost on Android >=5.0

通常是的,但具体影响可能会有所不同。

or the optimizations made on L make the use of inBitmap not necessary (not worth added complexity)?

ART 的垃圾收集器有多种改进。最重要的是它 压缩或移动收集器,尽管只有当您的应用程序处于后台时,这对您的情况没有太大帮助。

但是,ART 也有一个单独的堆区域用于大字节数组(或其他没有任何指向其内部其他对象的指针的大对象)。 ART 在收集这些方面效率更高,并且它们会导致更少的堆碎片。

话虽如此,我仍然会使用 inBitmap。如果您的 minSdkVersion 是 21 岁以上, 可能 您可以尝试跳过 inBitmap 并看看结果如何。但是,如果您的 minSdkVersion 低于 21,则无论如何您都需要 inBitmap,我会全面使用该代码。