android 计算bitmap的大小 bitmap内存大小计算_android 计算bitmap的大小

前言

加载一张Bitmap图片,占用内存是多大呢?

1简介

我们在开发程序过程中,经常会碰到OOM问题,分析问题,发现主要和图片相关,只知道需要去缩减图片大小。但还完全不懂得一张图片具体占用了多少内存空间?我第一次碰到这样的问题也很疑惑,那就让我们一起来解开这个谜题。(以下图片以Bitmap代替)

2计算公式

目前大家比较公认的计算公式如下

bitmap占用内存 = bitmap的宽度 x bitmap的长度 x 单位像素占用的字节数。

从上面可以看得出,最直接的影响那就是bitmap的宽度和长度,而不是bitmap的占用存储空间大小。当然还有一个很重要的因子——“单位像素占用的字节数”,这个因子是变化的。

3可变因子

从上述公式里面提到的“单位像素占用的字节数”,其实是不一样的,这个不一样,则取决于将Bitmap读取到内存时设置的参数。

我们一般通过BitmapFactory.decodeXXX 方法里面可以传入BitmapFactory.Options参数。而该参数底下有一个inPreferredConfig参数,Bitmap.Config类型,它是枚举类型,值可以是

ALPHA_8

只有透明度,没有任何RGB值,一个像素占用1个字节(byte)。

ARGB_4444

每一个像素点由4个,A(Alpha)、R(Red)、G(Green)、B(Blue)值表示。每一个占用4位(bit),所以总共占用16bit=16/8(byte)=2byte。也即每一个像素占用2字节。

这种格式的图片,显示效果会比较差,不推荐使用。

ARGB_8888

android手机上默认的格式,同时也是电脑上通用的格式。也是由4个值表示的,但每一个值占用8bit,所以总共是32bit=4byte。也即每一个像素占用4个字节。

RGB_565

没有透明度(alpha),所以,没法支持半透明或是全透明。只有R(占用5bit),G(占用6bit),B(占用5bit),总共16bit=2byte。也即,每一个像素占用2字节。

4占用内存实例

有了上述的公式,那么我们可以来算一笔账。如果一个有一张100x100的图片,使用不同可变因子的情况下,它实际占用内存是多大的呢?

1)ALPHA_8
100 x 100 x 1byte = 10000byte ≈ 10k
2)ARGB_4444
100 x 100 x 2byte = 20000byte ≈  20k
3)ARGB_8888
100 x 100 x 4byte = 40000byte≈  40k (标准)
4)RGB_565
100 x 100 x 2byte = 20000byte≈  20k

由于图片占用内存指的就是在Native中占用的内存,因为我们可以简单在认为这个就是bitmap实际占用的内存。

5内存回收

Android在4.0之前,Bitmap的内存是分配在Native(C/C++)堆中的,可以调用recycle()方法来回收内存。

但在Android 4.0开始,Bitmap的内存是分配在Dalvik堆中(Java),即使调用recycle(),也不会立马回收内存,但建议继续使用这个方法来回收。

使用recycle的技巧如下:

// 先判断是否已经回收
if(bitmap !=null
&& !bitmap.isRecycled()){
// 回收并且置为null
bitmap.recycle();
bitmap = null;
}

因为,建议在Bitmap不用的情况下,主动回收资源,同时如果定义Bitmap或Drawable的变量,建议采用WeakReference引用。一旦系统发现内存不足,会主动回收资源,使用弱引用,可以让系统尽可能释放更多的内存,从而避免OOM。