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

标签 java android bitmap garbage-collection bitmapfactory

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

我注意到当我足够快地向上/向下滚动时 GC 如果 super 活跃,这会使滚动变得不稳定。

Systrace dump

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

RAM

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

最佳答案

在 Android 中处理内存的一般方法与环境问题的口头禅相同:减少、重用、回收。 “减少”意味着“减少请求”(例如,在 BitmapFactory.Options 上使用 inSampleSize 以仅加载缩减采样图像)。 “回收”的意思是“确保它能尽快被垃圾回收”。

但是,在“回收”之前还有“再利用”。 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 在收集这些方面效率更高,并且它们会导致更少的堆 fragment 。

话虽如此,我仍然会使用 inBitmap。如果您的 minSdkVersion 是 21+,也许 您可以尝试跳过 inBitmap 并查看它的运行情况。但是,如果您的 minSdkVersion 低于 21,则无论如何您都需要 inBitmap,我会全面使用该代码。

关于java - GC 在 BitmapFactory.decodeStream() 上过于活跃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32701480/

相关文章:

java - 根据从 XML 文件中解析信息的 vector 绘制 ListField 并使用 Graphics 绘制屏幕

java - 只要 editText 变空,SPAN_EXCLUSIVE_EXCLUSIVE 跨度就不能有零长度错误

java - JDOQL中如何实现SQL IN查询?

java - Android iText 文本提取

java - Android 中使用 DataAdapter 在 GridView 中显示数据

Android - 处理在 Vector 类中分配的位图

android - 如何在 Canvas 上用 x 点旋转位图?

iphone - iOS:如何从二进制数据创建位图并将其作为图像保存在设备上?

java - 使用 Java 泛型计算 2 个集合之间逐个元素的算术差异

java - 用\n替换换行符