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

2023-10-29

背景

在某个版本应用上线后,偶然测得首页占用的内存非常的大而且一直不能回收掉,经过一轮的排查后最终确定是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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android Bitmap加载内存占用彻底分析 的相关文章

  • 如何快速自动发送FCM或APNS消息?

    我正在开发一项后端服务 通过 FCM 或 APNS 向移动应用程序发送推送通知 我想创建一个可以在一分钟内运行的自动化测试 并验证服务器是否可以成功发送通知 请注意 我不一定需要检查通知是否已送达 只需检查 FCM 或 APNS 是否已成功
  • Android Studio 3.0 Canary 9 - 无法解析包

    我在 Android Studio 3 0 Canary 9 中遇到几个错误 这些错误是 无法解析 android 软件包 下面列出了一些错误 我刚刚安装了 SDK 的所有额外软件包 但仍然收到 gradle 构建错误 Error 82 1
  • Android 30+ 中的视频捕获意图 - 只有所有者才能与待处理项目交互

    我正在尝试在我的应用程序上捕获视频 它可以在 android API 30 以下运行 但不能在 30 以上运行 似乎在 sdk 30 之后 android 不允许完全读取外部存储 作用域存储 我目前遇到这个错误 java lang Ille
  • 找不到 com.google.firebase:firebase-core:9.0.0 [重复]

    这个问题在这里已经有答案了 在遵循有些不一致的指示之后here https firebase google com docs admob android quick start name your project and here http
  • 在画布上绘图

    我正在编写一个 Android 应用程序 它可以在视图的 onDraw 事件上直接绘制到画布上 我正在绘制一些涉及单独绘制每个像素的东西 为此我使用类似的东西 for int x 0 x lt xMax x for int y 0 y lt
  • 在 java 类和 android 活动之间传输时音频不清晰

    我有一个android活动 它连接到一个java类并以套接字的形式向它发送数据包 该类接收声音数据包并将它们扔到 PC 扬声器 该代码运行良好 但在 PC 扬声器中播放声音时会出现持续的抖动 中断 安卓活动 public class Sen
  • 无法访问 com.google.android.gms.internal.zzbfm 的 zzbfm 类文件未找到

    我正在将我的 Android 应用程序项目从GCM to FCM 为此 我使用 Android Studio 中的 Firebase 助手工具 并遵循 Google 开发人员指南中的说明 一切都很顺利 并将我的应用程序代码更改为FCM根据助
  • Android:捕获的图像未显示在图库中(媒体扫描仪意图不起作用)

    我遇到以下问题 我正在开发一个应用程序 用户可以在其中拍照 附加到帖子中 并将图片保存到外部存储中 我希望这张照片也显示在图片库中 并且我正在使用媒体扫描仪意图 但它似乎不起作用 我在编写代码时遵循官方的Android开发人员指南 所以我不
  • 是否有 ADB 命令来检查媒体是否正在播放

    我想使用 ADB 命令检查根植于终端的外部设备中是否正在播放音频 视频 我无法找到任何 ADB 命令 如果有 我尝试过 adb shell dumpsys media player 我想要一个命令来指定视频是否正在运行 您可以使用以下命令查
  • 控制Android的前置LED灯

    我试图在用户按下某个按钮时在前面的 LED 上实现 1 秒红色闪烁 但我很难找到有关如何访问和使用前置 LED 的文档 教程甚至代码示例 我的意思是位于 自拍 相机和触摸屏附近的 LED 我已经看到了使用手电筒和相机类 已弃用 的示例 但我
  • 你的CPU不支持NX

    我刚刚下载了 android studio 但是我遇到了一个问题 当我运行它时 它说你的 cpu 不支持 NX 我应该怎么办 NX 或实际上是 NX 处理器位 是处理器的一项功能 有助于保护您的 PC 免受恶意软件的攻击 当此功能未启用并且
  • 如何发布Android .aar源以使Android Studio自动找到它们?

    我正在将库发布到内部 Sonatype Nexus 存储库 Android Studio 有一个功能 可以自动查找通过 gradle 引用的库的正确源 我将 aar 的源代码作为单独的 jar 发布到 Nexus 但 Android Stu
  • 错误:在根项目“projectName”中找不到项目“app”

    我有一个在 Eclipse 中开发的旧应用程序 现在尝试将其迁移到 Android Studio 我更新了库并遵循了基本步骤 现在 我收到此错误 Error Project app not found in root project pro
  • 我的设备突然没有显示在“Android 设备选择器”中

    我正在使用我的三星 Galaxy3 设备来测试过去两个月的应用程序 它运行良好 但从今天早上开始 当我将设备连接到系统时 它突然没有显示在 Android 设备选择器 窗口中 我检查过 USB 调试模式仅在我的设备中处于选中状态 谁能猜出问
  • 如何确定对手机号码的呼叫是本地呼叫还是 STD 或 ISD

    我正在为 Android 开发某种应用程序 但不知道如何获取被叫号码是本地或 STD 的号码的数据 即手机号码检查器等应用程序从哪里获取数据 注意 我说的是手机号码 而不是固定电话 固定电话号码 你得到的数字是字符串类型 因此 您可以获取号
  • Firebase 添加新节点

    如何将这些节点放入用户节点中 并创建另一个节点来存储帖子 我的数据库参考 databaseReference child user getUid setValue userInformations 您需要使用以下代码 databaseRef
  • 将两个文本视图并排放置在布局中

    我有两个文本视图 需要在布局中并排放置 并且必须遵守两条规则 Textview2 始终需要完整显示 如果布局中没有足够的空间 则必须裁剪 Textview1 例子 文本视图1 文本视图2 Teeeeeeeeeeeeeeeeeextview1
  • android sdk 的位置尚未在 Windows 操作系统的首选项中设置

    在 Eclipse 上 我转到 windows gt Android SDK 和 AVD Manager 然后弹出此消息 Android sdk 的位置尚未在首选项中设置 进入首选项 在侧边栏找到 Android 然后会出现一个 SDK 位
  • 如何将 google+ 登录集成到我的 Android 应用程序中?

    大家好 实际上我需要通过我的应用程序从 google 登录人们 现在我阅读了 google 上的文档 其中指出 要允许用户登录 请将 Google Sign In 集成到您的应用中 初始化 GoogleApiClient 对象时 请求 PL
  • 按日期对 RecyclerView 进行排序

    我正在尝试按日期对 RecyclerView 进行排序 但我尝试了太多的事情 我不知道现在该尝试什么 问题就出在这条线上适配器 notifyDataSetChanged 因为如果我不放 不会显示错误 但也不会更新 recyclerview

随机推荐

  • f12获取网页文本_网页上的文字不能复制怎么办?有这5招轻松复制

    有时候我们需要一些辅助资料时 会经常使用搜索工具查坎相关网页文件 但遇到一些需要用到的段落却不能直接复制时 一个字一个字的敲肯定是不现实 有什么方法可以让其直接进行复制呢 方法1 打印网页 这种方式相对比较简单 而且电脑也不需要真的安装打印
  • 串行通信协议---HART协议

    实际应用中 HART协议是仅次于Modbus协议的最接近统一现场总线的标准 主要是在4 20mA电流信号上面叠加数字信号 物理层采用Bell 202标准的FSK技术成功实现模拟信号和数字信号双向同时通信而互不干扰 HART协议规定了传输的物
  • 怎么启用windwos无线网驱动

    重启windwos无线网驱动 说明 进入系统窗口 打开设备管理器 在设备管理器目录中找到网络适配器 找到 Realtek 8822BE Wireless LAN 802 11ac PCI ENIC 左键选中Realtek 8822BE Wi
  • 【QT5】tslib移植

    tslib全称应该是Touch Screen Library 也就是专门针对触摸屏创建的开源库 tslib的最新工程的github地址为 https github com libts tslib 感谢牛人的开源工程 clone下来 进入源码
  • 使用Visual Studio开发Linux程序

    首先我们使用visual studio创建项目 这里我使用的是visual studio 2022 visual studio 2019的也一样 如下创建项目即可 然后我们需要在visual studio中连接我们的Linux服务器 点击
  • 刷脸支付顺应时代各种优惠政策出现

    相比于人工合成的二维码扫码支付 刷脸支付采用的是生物信息识别技术 在安全性上后者要比前者高很多 刷脸支付自从出世以来就受到广大创业者 商家的关注 自从去年支付宝推出刷脸支付并在实体店投入运营 到今年刷脸支付得到快速的发展 微信也加入刷脸支付
  • 后台运行VirtualBox虚拟机

    运行一个VirtualBox虚拟机最常见的方式是 打开VirtualBox 点击对应的虚拟机来运行 使用这种传统方式运行的虚拟机通常都有一个前台界面 可以像操作本地电脑一样进行操作 但是Linuxer有时候更喜欢通过终端远程接入 而不是在虚
  • 手撕/手写/自己实现 BN层/batch norm/BatchNormalization python torch pytorch

    计算过程 在卷积神经网络中 BN 层输入的特征图维度是 N C H W 输出的特征图维度也是 N C H W N 代表 batch size C 代表 通道数 H 代表 特征图的高 W 代表 特征图的宽 我们需要在通道维度上做 batch
  • 51单片机上连YL69土壤湿度传感器获取的数据在LCD上显示出来

    要做一个项目 被分配到做DS18B20温度传感与YL69土壤湿度传感器在51单片机上用LCD显示屏显示出来 温度传感模块很简单 网上到处都是资料 但是YL69的资料就很少了 特别还是在51单片机上实现 其实懂了原理也还是简单 将传感器的AO
  • 高并发+海量数据下如何实现系统解耦?【上】

    V xin ruyuanhadeng获得600 页原创精品文章汇总PDF 一 写在前面 之前更新过一个 亿级流量系统架构 系列 主要讲述了一个大规模商家数据平台的如下几个方面 如何承载百亿级数据存储 如何设计高容错的分布式架构 如何设计承载
  • 拓端tecdat

    最近我们被客户要求撰写关于偏最小二乘法 PLS 回归的研究报告 包括一些图形和统计输出 本文建立偏最小二乘法 PLS 回归 PLSR 模型 以及预测性能评估 为了建立一个可靠的模型 我们还实现了一些常用的离群点检测和变量选择方法 可以去除潜
  • 全国程序员收入大调查,粒度到省

    2019年五一假期 我没休息 而是统计某招聘网站了全国的程序员工资 总体统计 2019年4月全国招收程序员302303人 2019年4月全国程序员平均工资12807元 工资中位数11500元 其中95 的人的工资介于3750元到32500元
  • (python算法)LeetCode-版本号比较

    第一次笔试 发挥的很糟糕 基础不好是硬伤 碰到了版本号比较这个问题 回来后搜了下 发现在LeetCode里有 正好再仔细研究下 以下是原题 比较两个版本号 version1 和 version2 如果 version1 gt version
  • python怎么一步步调试_PyCharm入门第一步(二)——调试第一个Python应用程序

    第2步 调试您的第一个Python应用程序 找出问题的根源 PyCharm报告运行时错误 a ZeroDivisionError 深入研究一下代码 找出问题所在 这里可以使用PyCharm调试器来查看代码中发生了什么 要开始调试 您必须先设
  • 【珍藏版】 2012Java开发工程师必备精品资料(115个)

    Java应用广泛 涉及个人PC 数据中心 游戏控制台 科学超级计算机 移动电话和互联网等领域 同时拥有全球最大的开发者专业社群 小弟精心整理了115个精品资料 包括11个Java开发专题和104个热门资源 网上的资料众多 参差不齐 然而这批
  • PHPBONE使用问题集--.Net直接POST数据被过滤

    当 NET用POST发送数据到服务端时 发现 加号全被过滤成空格了 以为是PHPBONE的问题 查了半天代码也没发现哪有异常 但是以前也遇到过 也的确是处理过 只是不记得是怎么处理的了 无耐翻出以前的程序查找了一番 结果发现是编码问题 把数
  • 2021-07-18

    JQuery之DOM操作 1 创建节点及结点属性 1 DOM创建节点及结点属性 创建流程比较简单 大体如下 创建节点 常见的 元素 属性和文本 添加节点的一些属性 加入到文档中 流程中涉及的一点方法 创建元素 document create
  • 哲学家问题(死锁问题)

    1 问题描述 有五个哲学家绕着圆桌坐 每个哲学家面前有一盘面 两人之间有一支筷子 这样每个哲学家左右各有一支筷子 哲学家有2个状态 思考或者拿起筷子吃饭 如果哲学家拿到一只筷子 不能吃饭 直到拿到2只才能吃饭 并且一次只能拿起身边的一支筷子
  • git从某个分支创建新分支

    如题 记录一下从某个分支创建新分支的方法 如从dev分支创建一个test分支 第一步 切换到你指定的分支 如我要从dev上拉一个分支 代码一模一样 git checkout dev 第二步 拉取dev的最新代码 git pull 第三步 在
  • Android Bitmap加载内存占用彻底分析

    背景 在某个版本应用上线后 偶然测得首页占用的内存非常的大而且一直不能回收掉 经过一轮的排查后最终确定是3张图片引起的 当时每张图片占用了将近20m内存 当时紧急处理好后还一直惦记着此事 后来对Android加载Bitmap的内存占用作了彻