Android没有从内存中释放Bitmap

时间:2013-09-17 11:50:05

标签: android memory-management bitmap out-of-memory

我在应用程序中处理了我的位图:

  1. LruCacheBitmaps,大小为内存的1/8
  2. 使用BitmapFactory.Options计算inSampleSize
  3. 在创建OOM时抓住Bitmaps,在那里调用evictAllSystem.gc()
  4. 有时AsyncTask
  5. 会有Bitmaps解码

    我使用BitmapFactory.decodeFile,看起来VM并没有从内存中快速释放Bitmaps。我在某处读到可能存在使用BitmapFactory.decodeFile的错误,因此我尝试使用BitmapFactory.decodeFileDescriptor,但我随机得到以下内容:

    skia --- decoder-> decode返回false

    如果我不想使用FileInputStream或其他事情做,那么BitmapFactory.decodeFileDescriptor需要解决此问题。

    这花了我太多时间,我已经阅读了基于此的所有解决方案以及Google如何处理Bitmap处理并且我已经走到了尽头。

    感谢。

4 个答案:

答案 0 :(得分:2)

使用大型Bitmap总是有机会获得Out Of Memory Exception。 所以要处理通过Android博客

http://developer.android.com/training/displaying-bitmaps/index.html

并且总是回收Bimap

ImageView mImage;
Drawable toRecycle = mImage.getDrawable();
        if ( toRecycle != null && toRecycle instanceof BitmapDrawable ) {
            if ( ( (BitmapDrawable) mImage.getDrawable() ).getBitmap() != null )
                ( (BitmapDrawable) mImage.getDrawable() ).getBitmap().recycle();
        }

答案 1 :(得分:2)

请查看此链接

https://github.com/nostra13/Android-Universal-Image-Loader

我认为这可能有助于你。

答案 2 :(得分:2)

我最终在SoftRefences使用了Bitmap。现在,当我快速滚动Bitmaps时,我可以看到GC释放未使用的GridView

经过测试设置我的LruCache大小的完整内存大小但仍未获得OOM。

使用此方法的惩罚并不明显,我的GridView滚动非常顺利,因为它正在绘制非常自定义的图像。

答案 3 :(得分:0)

System.gc()不会帮助您,也不保证任何内容。

如果您完全确定,不再需要已逐出的位图,并且在任何地方都没有引用它们(否则会捕获“无法绘制回收的位图”异常)我建议您将EvictionListener添加到LRU缓存中对每个被驱逐的值调用bitmap.recycle()。

不记得默认LRU缓存是否提供了设置逐出侦听器的便捷方法,但如果没有,则扩展它并添加所需功能非常容易。

P.S。我建议不要使用WeakReferences,因为你失去了对你的位图和LRU目的的任何控制。即使你加载的8位图很适合1/8的内存,但是屏幕一次只能显示4个(ImageViews对位图有很强的参考),gc会尽快清除剩余的4位。我的意思是超快。您必须为要显示的每个新行(如果是ListView)重新加载位图。每个位于屏幕外的位图都必须重新加载。