文档章节

[Android] Bitmap OOM解决办法一

枫兮兮
 枫兮兮
发布于 2014/02/11 17:10
字数 1220
阅读 5921
收藏 2

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图,
因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存。

因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的 source,decodeStream最大的秘密在于其直接调用JNI>>nativeDecodeAsset()来完成decode,无 需再使用java层的createBitmap,从而节省了java层的空间。

如果在读取时加上图片的Config参数,可以跟有效减少加载的内存,从而跟有效阻止抛out of Memory异常
另外,decodeStream直接拿的图片来读取字节码了, 不会根据机器的各种分辨率来自动适应, 使用了decodeStream之后,需要在hdpi和mdpi,ldpi中配置相应的图片资源, 否则在不同分辨率机器上都是同样大小(像素点数量),显示出来的大小就不对了。

另外,以下方式也大有帮助:

1
2
3
4
5
InputStream is = this.getResources().openRawResource(R.drawable.pic1);
     BitmapFactory.Options options=new BitmapFactory.Options();
     options.inJustDecodeBounds = false;
     options.inSampleSize = 10;   //width,hight设为原来的十分一
     Bitmap btp =BitmapFactory.decodeStream(is,null,options);
1
2
3
4
if(!bmp.isRecycle() ){
         bmp.recycle()   //回收图片所占的内存
         system.gc()  //提醒系统及时回收}

以下奉上一个方法:

``java
  /**
   * 以最省内存的方式读取本地资源的图片
   * @param context
   * @param resId
   * @return
   */

  public static Bitmap readBitMap(Context context, int resId){

      BitmapFactory.Options opt = new BitmapFactory.Options();

      opt.inPreferredConfig = Bitmap.Config.RGB_565;

      opt.inPurgeable = true;

      opt.inInputShareable = true;

         //获取资源图片

      InputStream is = context.getResources().openRawResource(resId);

          return BitmapFactory.decodeStream(is,null,opt);

  }

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
================================================================================
Android内存溢出的解决办法

转自:http://www.cppblog.com/iuranus/archive/2010/11/15/124394.html?opt=admin

昨天在模拟器上给gallery放入图片的时候,出现java.lang.OutOfMemoryError: bitmap size exceeds VM budget 异常,图像大小超过了RAM内存。

      模拟器RAM比较小,只有8M内存,当我放入的大量的图片(每个100多K左右),就出现上面的原因。
由于每张图片先前是压缩的情况,放入到Bitmap的时候,大小会变大,导致超出RAM内存,具体解决办法如下:

```java
//解决加载图片 内存溢出的问题
                    //Options 只保存图片尺寸大小,不保存图片到内存
                BitmapFactory.Options opts = new BitmapFactory.Options();
                //缩放的比例,缩放是很难按准备的比例进行缩放的,其值表明缩放的倍数,SDK中建议其值是2的指数值,值越大会导致图片不清晰
                opts.inSampleSize = 4;
                Bitmap bmp = null;
                bmp = BitmapFactory.decodeResource(getResources(), mImageIds[position],opts);                             

                ...              

               //回收
                bmp.recycle();

通过上面的方式解决了,但是这并不是最完美的解决方式。

通过一些了解,得知如下:

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

对于Android平台来说,其托管层使用的Dalvik JavaVM从目前的表现来看还有很多地方可以优化处理,比如我们在开发一些大型游戏或耗资源的应用中可能考虑手动干涉GC处理,使用 dalvik.system.VMRuntime类提供的setTargetHeapUtilization方法可以增强程序堆内存的处理效率。当然具体 原理我们可以参考开源工程,这里我们仅说下使用方法:   private final static floatTARGET_HEAP_UTILIZATION = 0.75f; 在程序onCreate时就可以调用 VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION); 即可。

Android堆内存也可自己定义大小

对于一些Android项目,影响性能瓶颈的主要是Android自己内存管理机制问题,目前手机厂商对RAM都比较吝啬,对于软件的流畅性来说 RAM对性能的影响十分敏感,除了 优化Dalvik虚拟机的堆内存分配外,我们还可以强制定义自己软件的对内存大小,我们使用Dalvik提供的 dalvik.system.VMRuntime类来设置最小堆内存为例:

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

VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE); //设置最小heap内存为6MB大小。当然对于内存吃紧来说还可以通过手动干涉GC去处理

bitmap 设置图片尺寸,避免 内存溢出 OutOfMemoryError的优化方法
★android 中用bitmap 时很容易内存溢出,报如下错误:Java.lang.OutOfMemoryError : bitmap size exceeds VM budget

● 主要是加上这段:

1
2
BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize = 2;

● eg1:(通过Uri取图片)

1
2
3
4
5
6
private ImageView preview;BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inSampleSize = 2;//图片宽高都为原来的二分之一,即图片为原来的四分之一
                    Bitmap bitmap = BitmapFactory.decodeStream(cr
                            .openInputStream(uri), null, options);
                    preview.setImageBitmap(bitmap);

以上代码可以优化内存溢出,但它只是改变图片大小,并不能彻底解决内存溢出。
● eg2:(通过路径去图片)

1
2
3
4
5
6
7
private ImageView preview;private String fileName= "/sdcard/DCIM/Camera/2010-05-14 16.01.44.jpg";BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize = 2;//图片宽高都为原来的二分之一,即图片为原来的四分之一
                        Bitmap b = BitmapFactory.decodeFile(fileName, options);
                        preview.setImageBitmap(b);
                        filePath.setText(fileName);


本文转载自:http://my.eoe.cn/littlebirds/archive/4646.html

枫兮兮
粉丝 14
博文 72
码字总数 27211
作品 0
成都
私信 提问
Android Bitmap变迁与原理解析(4.x-8.x)

App开发不可避免的要和图片打交道,由于其占用内存非常大,管理不当很容易导致内存不足,最后OOM,图片的背后其实是Bitmap,它是Android中最能吃内存的对象之一,也是很多OOM的元凶,不过,在...

看书的小蜗牛
2018/05/22
0
0
Android 图片加载图片_OOM异常解决

http://stormzhang.github.io/android/2013/11/20/android-display-bitmaps-efficiently/ Android加载资源图片时,很容易出现OOM的错误。 因为Android系统对内存有一个限制,如果超出该限制,...

mstian06
2014/07/02
2.9K
0
Android内存泄露与内存溢出

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zping0808/article/details/53889115 一、 内存泄漏与内存溢出(OOM) 1. 内存泄露 垃圾回收器无法回收原本应...

_zping
2016/12/26
0
0
bitmap报OOM问题

@邓凡平 你好,想跟你请教个问题: 我在做给图片添加水印功能的时候,出现这样一个问题,先是报OOM问题,然后我在网上查资料知道bitmap很占内存需要及时回收,所以我又写了一个回收bitmap的方...

wangxudong
2012/10/16
1K
3
[Android] Bitmap OOM解决办法三

在最近做的工程中发现加载的图片太多或图片过大时经常出现OOM问题, 常用的解决方案如下几种: 一:在内存中加载图片时直接在内存中做处理,如:边界压缩 二:动态回收内存 三:优化Dalvik虚拟...

枫兮兮
2014/02/11
212
0

没有更多内容

加载失败,请刷新页面

加载更多

是否有内置功能可以打印对象的所有当前属性和值?

所以我在这里寻找的是类似PHP的print_r函数。 这样一来,我可以通过查看问题对象的状态来调试脚本。 #1楼 可能值得一看- 是否有与Perl的Data :: Dumper等效的Python? 我的建议是 https://gi...

技术盛宴
24分钟前
5
0
直击面试,聊聊 GC 机制

前言 文章来源:https://studyidea.cn/ GC 中文直译垃圾回收,是一种回收内存空间避免内存泄漏的机制。当 JVM 内存紧张,通过执行 GC 有效回收内存,转而分配给新对象从而实现内存的再利用。 ...

程序通事
26分钟前
4
0
Mybatis where 1=1 和 标签

在mybatis中拼接查询语句,偶尔会出现where后面可能一个字段的值都没有,就导致所有条件无效,导致where没有存在的意义;但也有可能这些条件会存在。那解决这个问题的方法,最常见的就是: ...

观海562
29分钟前
4
0
git常用初始化设置

日志编辑工具 git config --global core.editor vim ssh访问 cd /home/weiguangyue/.sshssh-keygen -t rsa -C weiyue888999@126.com 提交者信息用户名 git config --global user.nam......

萧默
30分钟前
4
0
面试题-关于Java线程池一篇文章就够了

在Java面试中,线程池相关知识,虽不能说是必问提,但出现的频次也是非常高的。同时又鉴于公众号“程序新视界”的读者后台留言让写一篇关于Java线程池的文章,于是就有本篇内容,本篇将基于J...

程序新视界
33分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部