zoukankan      html  css  js  c++  java
  • Android大图片引起的内存问题(OOM)

    在Android应用开发中,对一个应用在内存使用大小是有限制。在应用中如果大量的使用Bitmap很有可能导致内存溢出的问题(OOM),出现这种问题后,第一感觉就是头疼,但是又不得不解决,在网上查了一些资料后,找到解决方法。


    问题描述:

    在一个项目中,要用Gallery来显示多张不同的图片,在给Gallery的每个Item设置图片显示时,想到Bitmap如果不手动的recycle,系统是不会回收其所在的资源的,因为Android为了提高效率,Bitmap真正的位图数据是在ndk中C写的。所以就直接使用setImageResource(iconResId); 但是在部分配置比较低的设备上还是出现OOM错误。


    问题分析:

    在setImageResource中,是根据iconResId的到一个drawable,在将drawable显示在view中。在查阅资料后得知:Android对于直接通过资源id载入的资源做了Cache,这样下次再需要次资源时直接从cache中得到。

    在Gallery中用到多个大的图片,每个图片都会在cache中进行缓存,即使在Gallery中该View被回收了。这就是导致内存溢出的问题


    问题解决:

    解决的一般办法:

    一:在内存引用上做些处理,常用的有软引用、强化引用、弱引用

    二:在内存中加载图片时直接在内存中做处理,如:边界压缩

    三:动态回收内存

    四:优化Dalvik虚拟机的堆内存分配

    五:自定义堆内存大小


    在项目中主要将前两种方法进行了整合。

    1. private static LinkedHashMap<String, Bitmap> hardManager;  
    2.     private static ConcurrentHashMap<String, SoftReference<Bitmap>> softManager;  

    设置上面的两个变量,分别保存包名到Bitmap的强引用的映射和软引用的映射。

    在通过包名获取bitmap时,首先在hardManager中判断是否包含该包名,如果有,直接取出;如果没有,则在softManager中判断,有取出;没有就通过下面方法获取。获取之后在插入到hardManager中。在插入时,做判断只保证hardManager的容量为10,如果大于10,则将最早插入的删除。

    1. private static Bitmap readBitMap(Context context, int resId) {  
    2.         BitmapFactory.Options opt = new BitmapFactory.Options();  
    3.         opt.inPreferredConfig = Bitmap.Config.RGB_565;  
    4.         opt.inPurgeable = true;  
    5.         opt.inInputShareable = true;  
    6.         // 获取资源<strong>图片</strong>  
    7.         InputStream is = context.getResources().openRawResource(resId);  
    8.         return BitmapFactory.decodeStream(is, null, opt);  
    9.     }  

    参考资料:

    http://www.cnblogs.com/siyiganshou/archive/2012/08/10/2631727.html

    http://www.cnblogs.com/siyiganshou/archive/2012/08/10/2631755.html

    http://www.cnblogs.com/siyiganshou/archive/2012/08/10/2631727.html


    关于Android 内存优化测试 比较DrawableBitmap占用内存大小 中,作者的疑惑就是应用Drawable会进行缓存,所以在同样将一个图片加载1000次Drawable没有出现OOM的错误,而Bitmap出现了OOM错误。并不是因为Drawable所在的内存比Bitmap要小。


    关于Drawable和Bitmap到底谁在用的内存要小,大家感兴趣可以看看源码?

  • 相关阅读:
    多层神经网络与C++实现
    反向传导算法的推导
    sizeof()和strlen()的区别与联系
    Pascal’s Triangle
    Multiply Strings
    spring boot 数据源 配置
    spring boot 静态资源。。
    spring boot 配置 beetl 视图解析器
    spring 使用junit
    spring aspectj 注解
  • 原文地址:https://www.cnblogs.com/dongdong230/p/4183147.html
Copyright © 2011-2022 走看看