OOM(Out Of Memory)在加载图片过多或者过大的情况下会发生OOM,可以查看APP最高可用内存:

  int maxMemory = (int) (Runtim.getRuntime().maxMemory()/1024);

OOM问题如何解决?

解决方案:

1、使用强引用(StrongReference)、弱引用(WeakReference)、软引用(SoftReference)、虚引用(PhantomRefrence),在内存引用中做处理。

2、在内存加载图片的时候,在内存中处理图片(边界压缩等)。

3、动态回收内存。

4、优化Dalvik的堆内存分配。

5、自定义堆内存的大小。

下面是对以上几点的详细描述:

1、引用的处理。

  Heap中的对象有强可及、软可及、弱可及、虚可及和不可达对象。应用的强弱顺序是强、软、弱、虚。对于对象属于哪种可及对象,由它的最强引用决定。

  String abc = new String("abc"); // 建立强引用,内存中abc是强可及,不能释放内存。

  SoftReference<String> abcSoftRef = new SoftReference<String>(abc);// 建立软引用,仍然是强可及,不能释放内存。

  WeakReference<String> abcWeakRef = new WeakPeference<String>(abc);//建立弱引用,强可及,不能释放内存。

  abc = null;// 强引用取消,变成软可及

  abcSoftRef.clear();//软引用取消,变成弱可及

总结:

  强引用:只能释放没有强引用指向的内存。http://i.cnblogs.com/EditPosts.aspx?postid=5543041

  弱引用:当Dalvik内存不足时,可以释放引用指向的内存。 

  软引用:无条件的执行Dalvik的指令。

  虚引用:和以上引用不一样,跟踪引用的释放过程。

2、图片处理

  BitmapFactory提供了多个方法decodeFile()解析SD卡中的图片、decodeResource()解析资源文件图片、decodeStream()解析网络图片。

  2.1 单一图片压缩

  public static int calculateInSampleSize(BitmapFactory.Options options,int reqWidth,int repHeight){

    final int height = options.outHeight;

    final int width = options.outWidth;

    int inSampleSize = 1;

    if(height > reqHeight || width > reqWidth){

      final int heightRatio = Math.round((float) height/(float) reqHeight);

        final int widthRatio = Math.round((float) width/(float) reqWidth);

      inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;

    }

    return inSampleSize;

  }

  public static Bitmap decodeSampleBitmapFromResource(Resource res, int resId,int reqWidth,int reqHeight){

    final BitmapFactory.Options options = new BitmapFactory.Options();

    options.inJustDecodeBounds = true;

    BitmapFactory.decodeResource(res, resId, options);

    options.inSampleSize = calculateInSampleSize(options,reqWidth,reqHeight);

    options.inJustDecodeBounds = false;

    return BitmapFactory.decodeResource(res,resId,options);

  }

  使用方式:

  imageView.setImageBitmap(decodeSampleBitmapFromResouce(getResource(),R.id.myimg,100,100));

  压缩流程:

  (1)、创建Options对象,将inJustDecodeBounds设置为true.

  (2)、解析图片,将属性值赋予options对象。

  (3)、计算压缩比例,将比例值赋予options的inSampleSize属性。

  (4)、将inJustDecodeBounds赋值false后,重新解析图片,返回Bitmap对象。

  2.2 批量图片处理

  处理单个照片的如上比较简单,但是一旦遇到批量图片处理,android为我们提供一个类LruCache,用于图片缓存(是一种内存缓存技术)。当缓存图片的数量到达预计设定的值的时候,近期使用比较少的图片会被回收掉。

  流程:

  private LruCache<String, Bitmap> mMemoryCache;

  private void initLurCache(){

    //1.设置缓存图片使用的内存大小,程序内存的八分之一。

    int cacheMemory = (int) (Runtime.getRuntime().maxMemory()/8);

    //2.初始化LruCache实例对象,重写sizeOf()、entryRemoved()方法。

    mMemoryCache = new LruCache<String, Bitmap>(cacheMemory){

  //必须重写此方法,来测量Bitmap的大小
              @Override
              protected int sizeOf(String key, Bitmap value) {
                  return value.getRowBytes() * value.getHeight();
              }
              @Override
              protected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) {
                  // TODO Auto-generated method stub
                  super.entryRemoved(evicted, key, oldValue, newValue);
                  removeBitmapCache(key);
              }
          };

  }

  //3.分别实现清空缓存、添加图片到缓存、获取图片、从缓存移除图片

  public void addBitmapToMemoryCache(String key, Bitmap bitmap) {  
          if (getBitmapFromMemCache(key) == null && bitmap != null) {  
              mMemoryCache.put(key, bitmap);  
         }  
     } 
     public Bitmap getBitmapFromMemCache(String key) {  
          return mMemoryCache.get(key);  
     }
     public void clearCache(){
          if (mMemoryCache != null && mMemoryCache.size() > 0) {
              mMemoryCache.evictAll();
          }
     }
     public void removeBitmapCache(String key){
          if (key != null && mMemoryCache != null) {
              Bitmap bitmap = mMemoryCache.remove(key);
              if (bitmap!=null) {
                  bitmap.recycle();
              }
          }
     }

3、动态回收内存

  显示调用recycle()方法让GC回收内存。

  if(!abc.isRecycled()){

  abc.recycle();

  }

4、优化Dalvik堆内存分配

  使用Dalvik.System.VMRuntime类提供的setTargetHeapUtilization()方法可以增强程序堆内存的处理效率。

  private final static float HEAP_UTILIZATION = 0.75f;

 //在onCreate()的时候调用

  Runtime.getRuntime().setTargetHeapUtilization(HEAP_UTILIZATION);

5、自定义内存

  private final static int HEAP_SIZE  = 6*1024*1024;

  Runtime.getRuntime().setMinimumHeapSize(HEAP_SIZE);

Android 开发OOM解决方案的更多相关文章

  1. 64位ubuntu搭建android开发环境问题解决方案

    安装32位库支持,删除eclipse 的配置文件和.android目录(测试环境ubuntu 14.04) sudo apt-get install libc6-i386 lib32stdc++6 l ...

  2. Android OOM 解决方案

    Out of Memory(内存溢出) 几乎是每个Android程序员都会遇到的事.在网上也能找到一大堆的解决方案,之前写过一篇<Android 内存溢出管理与测试>的博文.但感觉写得不是 ...

  3. Android开发笔记——图片缓存、手势及OOM分析

    把图片缓存.手势及OOM三个主题放在一起,是因为在Android应用开发过程中,这三个问题经常是联系在一起的.首先,预览大图需要支持手势缩放,旋转,平移等操作:其次,图片在本地需要进行缓存,避免频繁访 ...

  4. Android开发——常见的内存泄漏以及解决方案(一)

    0. 前言   转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52333954 Android的内存泄漏是Android开发领域永恒的 ...

  5. android 帧动画的实现及图片过多时OOM解决方案(一)

    一,animation_list.xml中静态配置帧动画的顺序,如下: <?xml version="1.0" encoding="utf-8"?> ...

  6. Android开发——Android M(6.0) 权限解决方案

    Android开发--Android M(6.0) 权限解决方案 自从Android M(6.0)发布以来,权限管理相比以前有了很大的改变,很多程序员发现之前运行的好好的Android应用在Andro ...

  7. Android开发——View滑动冲突解决方案

    0. 前言   我们在Android开发--事件分发机制详解中深入学习了事件分发机制,为我们解决Android开发中的滑动冲突问题做了初步准备.针对滑动冲突这里给出两种解决方案:外部拦截法和内部拦截法 ...

  8. Android开发——常见的内存泄漏以及解决方案(二)

    )Android2.3以后,SoftReference不再可靠.垃圾回收期更容易回收它,不再是内存不足时才回收软引用.那么缓存机制便失去了意义.Google官方建议使用LruCache作为缓存的集合类 ...

  9. 9种常见的Android开发错误及解决方案

    整理总结了9个Android开发中的错误以及解决方案,共同探讨进步! 1. 如果你的项目的R文件不见的话,可以试下改版本号在保存,R文件不见一般都是布局文本出错导致. 2. 布局文件不可以有大写字母 ...

随机推荐

  1. 《趣谈 Linux 操作系统》学习笔记(一):为什么要学 Linux 及学习路径

    前言:学习的课程来自极客时间的专栏<趣谈 Linux 操作系统>,作者用形象化的比喻和丰富的图片让课程变得比较易懂,为了避免知识看过就忘,打算通过写学习笔记的形式记录自己的学习过程. Li ...

  2. 剑指offer-面试题53_1-在排序数组中查找数字-二分查找

    /* 题目: 统计一个数字在排序数组中出现的次数. */ /* 思路: 1.从前往后遍历,时间复杂度O(n). 2.二分查找到目标数字target,向前向后遍历,时间复杂度O(n). 3.利用二分法, ...

  3. NIM游戏的Python实现

    可执行程序下载: 链接:https://pan.baidu.com/s/1xQedrWRBsqQRZvOe91Rvng 提取码:goi9 Nim游戏是博弈论中最经典的模型(之一),它又有着十分简单的规 ...

  4. github的版本控制master和branch develop

    一.git版本控制原理 master(主分支), develop(分支),虽然是主分支和分支,却是平级关系,develop可以理解为开发库,master为生产库. 本地版本:master, devel ...

  5. xctf-ics-07

    首先管理页面进入到云平台项目管理中心 发现下面可以查看源码,点击view-source: 这个直接就绕过去了 看第二个 第二个需要满足$_SESSION['admin']==true才行,因此看看第三 ...

  6. AMCL论文及源码解析--参数(持续更新中)

    整理内容来自:http://wiki.ros.org/amcl 1.AMCL订阅的节点: scan (sensor_msgs/LaserScan):激光数据 tf (tf/tfMessage):各种转 ...

  7. [Err] 1248 - Every derived table must have its own alias

    问题描述 [Err] 1248 - Every derived table must have its own alias 问题原因 这句话的意思是说每个派生出来的表都必须有一个自己的别名 我的Mys ...

  8. 基于EFCore3.0+Dapper 封装Repository

    Wei.Repository 基于EFCore3.0+Dapper 封装Repository,实现UnitOfWork,提供基本的CURD操作,可直接注入泛型Repository,也可以继承Repos ...

  9. tomcat-embeded-core源码编译

    使用spring-boot创建web工程时,默认采用embeded tomcat作为容器,实际使用过程中,可能会需要对其中的某些功能做微调,而tomcat又没有给出预留配 ,这时就需要对tomcat- ...

  10. docker镜像ubuntu封装jdk1.8.0【dockerfile】

    github地址:https://github.com/laileman/Docker/Dockerfile/ubuntu-jdk1.8.0_172 1-目录结构 2- dockerfile内容 3- ...