我有一个显示缩略图网格的应用程序。该应用使用 BitmapFactory.decodeStream()
将输入流解码为位图以显示每个缩略图。
我注意到当我足够快地向上/向下滚动时 GC 如果 super 活跃,这会使滚动变得不稳定。
我试图找出问题并编写了一个简单的应用程序,我在其中循环调用了 10000 次 decodeStream() 并注意到即使有足够的内存,GC 仍然会不断触发(即使我调用 bitmap.recycle()每次迭代后)。
问题:如何防止执行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/