Android Bitmap加载内存占用彻底分析

背景

在某个版本应用上线后,偶然测得首页占用的内存非常的大而且一直不能回收掉,经过一轮的排查后最终确定是3张图片引起的!当时每张图片占用了将近20m内存。当时紧急处理好后还一直惦记着此事,后来对Android加载Bitmap的内存占用作了彻底的分析,跟踪了相关的源码,在这里总结一下。

图片加载测试

先抛开结论,现在先直观的看一下加载如下一张图片需要多少内存

这里写图片描述

其中图片的宽高都为300像素

计算内存的方法采用 android.graphics.Bitmap#getByteCount

public final int getByteCount() {
    // int result permits bitmaps up to 46,340 x 46,340
    return getRowBytes() * getHeight();
}

预期占用的内存大小为

图片宽*图片高*表示每个像素点的字节数,即 

这里写图片描述

加载SD卡的图片

加载SD中的图片结果为

这里写图片描述

assets的图片

加载asset目录中的图片结果为

这里写图片描述

加载Resources的图片

  • drawable目录

    这里写图片描述

  • drawable-mdpi目录

    这里写图片描述

  • drawable-hdpi目录

    这里写图片描述

  • drawable-xhdpi目录

    这里写图片描述

  • drawable-xhhdpi目录

    这里写图片描述

  • drawable-xhhhdpi目录

    这里写图片描述

内存占用分析

理论上,300 * 300像素的图片,默认以4byte表示1个像素的情况下,占用的内存为
300 * 300 * 4 = 360000 byte

但是,实际上,只有从SD卡、assets目录、drawable-xhdpi目录下加载图片才等于理论数值,其他数值都不等!

等等!,从图片的大小看,不等于理论值的图片好像被放大或者缩小了?我们可以验证一下,把图片在内存中的实际宽高打印出来

SD卡的

这里写图片描述

drawable-mdpi的

这里写图片描述

发现没有?在drawable-mdpi目录中的图片在加载内存中时的宽高都放大了两倍!!
其实,加载在SD卡和assets目录的图片时,图片的尺寸不会被改变,但是drawable-xxxdpi目录的照片的尺寸会被改变,这里篇幅所限,就不一一截图了,想验证的可以下载demo(文末给出链接)试验一下。至于尺寸改变的原因,下文会讨论,这里卖个关子。

查看源码

正所谓源码面前,了无秘密,欲知原理,还须从源码下手,首先查看BitmapFactory.java文件

BitmapFactory.decodeFile 
BitmapFactory.decodeResourceStream

这两个方法的重载函数最终都会调用到

private static native Bitmap nativeDecodeStream(InputStream is, byte[] storage,
            Rect padding, Options opts);

这是一个本地方法,其相关实现在

frameworks/base/core/jni/android/graphics/BitmapFactory.cpp

打开文件,找到如下的方法,就是本地方法的实现

static jobject nativeDecodeStream(JNIEnv* env, jobject clazz, jobject is, jbyteArray storage,
        jobject padding, jobject options) {

    jobject bi
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值