Android Bitmap 计算内存
01.如何计算占用内存
- 如果图片要显示下Android设备上,ImageView最终是要加载Bitmap对象的,就要考虑单个Bitmap对象的内存占用了,如何计算一张图片的加载到内存的占用呢?其实就是所有像素的内存占用总和:
- bitmap内存大小 = 图片长度 x 图片宽度 x 单位像素占用的字节数
- 起决定因素就是最后那个参数了,Bitmap’常见有2种编码方式:ARGB_8888和RGB_565,ARGB_8888每个像素点4个byte,RGB_565是2个byte,一般都采用ARGB_8888这种。那么常见的1080*1920的图片内存占用就是:1920 x 1080 x 4 = 7.9M
02.上面计算内存对吗
- 说出我的结论:上面1.1这种说法也对,但是不全对,没有说明场景,同时也忽略了一个影响项:Density。接下来看看源代码。
- inDensity默认为图片所在文件夹对应的密度;inTargetDensity为当前系统密度。
- 加载一张本地资源图片,那么它占用的内存 = width * height * nTargetDensity/inDensity 一个像素所占的内存。
1 | @Nullable |
正确说法,这个注意呢?计算公式如下所示
- 对资源文件:width * height * nTargetDensity/inDensity * nTargetDensity/inDensity * 一个像素所占的内存;
- 别的:width * height * 一个像素所占的内存;
03.一个像素占用内存
- 一个像素占用多大内存?Bitmap.Config用来描述图片的像素是怎么被存储的?
- ARGB_8888: 每个像素4字节. 共32位,默认设置。
- Alpha_8: 只保存透明度,共8位,1字节。
- ARGB_4444: 共16位,2字节。
- RGB_565:共16位,2字节,只存储RGB值。
04.使用API获取内存
Bitmap使用API获取内存
getByteCount()
- getByteCount()方法是在API12加入的,代表存储Bitmap的色素需要的最少内存。API19开始getAllocationByteCount()方法代替了getByteCount()。
getAllocationByteCount()
- API19之后,Bitmap加了一个Api:getAllocationByteCount();代表在内存中为Bitmap分配的内存大小。
1
2
3
4
5
6
7
8public final int getAllocationByteCount() {
if (mRecycled) {
Log.w(TAG, "Called getAllocationByteCount() on a recycle()'d bitmap! "
+ "This is undefined behavior!");
return 0;
}
return nativeGetAllocationByteCount(mNativePtr);
}
思考: getByteCount()与getAllocationByteCount()的区别?
- 一般情况下两者是相等的;
- 通过复用Bitmap来解码图片,如果被复用的Bitmap的内存比待分配内存的Bitmap大,那么getByteCount()表示新解码图片占用内存的大小(并非实际内存大小,实际大小是复用的那个Bitmap的大小),getAllocationByteCount()表示被复用Bitmap真实占用的内存大小(即mBuffer的长度)。
在复用Bitmap的情况下,getAllocationByteCount()可能会比getByteCount()大。