文档章节

[Android] Bitmap OOM解决办法三

枫兮兮
 枫兮兮
发布于 2014/02/11 17:11
字数 574
阅读 210
收藏 1

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

三:优化Dalvik虚拟机的堆内存分配
  四:自定义堆内存大小

使用边界压缩的情况下间接的使用了软引用来避免OOM

private Map> map = new HashMap>();
      public void getBitmap(String path) {
            Options bitmapFactoryOptions = new BitmapFactory.Options();
             // 下面这个设置是将图片边界不可调节变为可调节
            bitmapFactoryOptions. inJustDecodeBounds = true;
            bitmapFactoryOptions. inSampleSize = 5;
                     Bitmap bitmap1 = BitmapFactory. decodeFile(path, bitmapFactoryOptions);
            int outWidth = bitmapFactoryOptions. outWidth;
            int outHeight = bitmapFactoryOptions. outHeight;
            float imagew = 150;
            float imageh = 150;
            int yRatio = ( int) Math. ceil(outHeight / imageh);
            int xRatio = ( int) Math. ceil(outWidth/ imagew);
            if (yRatio > 1 || xRatio > 1) {
                  if (yRatio > xRatio) {
                       bitmapFactoryOptions. inSampleSize = yRatio;
                 } else {
                       bitmapFactoryOptions. inSampleSize = xRatio;
                 }
           }
           bitmapFactoryOptions. inJustDecodeBounds = false;
           Bitmap  bitmap = BitmapFactory. decodeFile(path, bitmapFactoryOptions);
            //软引用
           SoftReference srf = new SoftReference(bitmap );
            map.put(path, srf);
     }

使用边界压缩的情况下间接的使用了软引用来避免OOM,但大家都知道,这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存,如果图片多且大,这种方式还是会引用OOM异常。
可以采用下面更测底的方式避免OOM:
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);
}
//显式调用GC来回收内存
if (bitmap .isRecycled()== false){
         bitmap.recycle();
        System.gc ();
}

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

自定义我们的应用需要多大的内存,这个好暴力哇,强行设置最小内存大小,代码如下:
private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ;
//设置最小heap内存为6MB大小
VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE);


本文转载自:http://my.eoe.cn/736513/archive/4925.html

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

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

看书的小蜗牛
2018/05/22
0
0
Android内存泄露与内存溢出

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

_zping
2016/12/26
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
bitmap报OOM问题

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

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

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

枫兮兮
2014/02/11
5.9K
0

没有更多内容

加载失败,请刷新页面

加载更多

JMM内存模型(一)&volatile关键字的可见性

在说这个之前,我想先说一下计算机的内存模型: CPU在执行的时候,肯定要有数据,而数据在内存中放着呢,这里的内存就是计算机的物理内存,刚开始还好,但是随着技术的发展,CPU处理的速度越...

走向人生巅峰的大路
20分钟前
42
0
你对AJAX认知有多少(2)?

接着昨日内容,我们几天继续探讨ajax的相关知识点 提到ajax下面几个问题又是必须要了解的啦~~~ 8、在浏览器端如何得到服务器端响应的XML数据。 通过XMLHttpRequest对象的responseXMl属性 9、 ...

理性思考
29分钟前
4
0
正则表达式基础(一)

1.转义 转义的作用: 当某个字符在表达式中具有特殊含义,例如字符串引号中出现了引号,为了可以使用这些字符本身,而不是使用其在表达式中的特殊含义,则需要通过转义符“\”来构建该字符转...

清自以敬
32分钟前
4
0
idea中@Data标签getset不起作用

背景:换电脑以后在idea中有@data注解都不生效 解决办法:idea装个插件 https://blog.csdn.net/seapeak007/article/details/72911529...

栾小糖
38分钟前
4
0
Apache Kudu 不能删除不存在的数据

使用Apache Kudu客户端,对KafkaConnect Sink 进行扩展。 使用的Apache Kudu 的Java 客户端。突然有天发现作业无法提交,一直报错。 后来才发现这是Kudu自身的一种校验机制。为了忽略这种校验...

吐槽的达达仔
48分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部