[Android] Bitmap内存在各系统版本的演化

聚焦的问题1、Bitmap的像素数据是存在哪里的?2、Bitmap内存如何释放?需要调用recycle吗?Bitmap bitmap = Bitmap.createBitmap(100,100,Bitmap.Config.ARGB_8888);以这样声明一个bitmap为例,有三个位置需要关注,bitmap引用本身所在的位置(栈),引用指向的对象所在的位置(堆),对象中持有的像素数据所在的…

大家好,又见面了,我是全栈君。

本文聚焦的问题
1、Bitmap的像素数据是存在哪里的?
2、Bitmap内存如何释放?需要调用recycle吗?

Bitmap bitmap = Bitmap.createBitmap(100,100,Bitmap.Config.ARGB_8888);

以这样声明一个bitmap为例,有三个位置需要关注,bitmap引用本身所在的位置(栈),引用指向的对象所在的位置(堆),对象中持有的像素数据所在的位置,像素数据在不同系统版本所在的位置略有不同,导致bitmap所占用的内存的释放方式也有所不同。

Android1.0~Android2.3

这几个版本Bitmap的像素数据是分配在Native内存中的,bitmap对象在Dalvik堆中占用的数据是很小的,只有width、height、config和指向堆的引用,这样的结果是bitmaps don’t get monitored well by the GC (it thinks they are the size of a reference),所以GC无法知道当前的内存情况是否乐观,大量创建bitmap可能不会触发到GC,而Native中bitmap的像素数据可能已经占用了过多内存,这时候就会OOM,所以推荐在bitmap使用完之后,调用recycle释放掉Native的内存。

Android3.0~Android7.1

这几个版本,Bitmap的数据结构发生了改变,其中多了如下属性,用来存储像素数据,

private byte[] mBuffer;

至此像素数据就和bitmap对象一起都分配在堆中了,一起接受GC管理,只要bitmap置为null没有被强引用持有,GC就会把它回收掉,和普通对象一样。

Android8.0+

这里开始,Bitmap的像素数据又重新回到native分配了,Bitmap数据结构中

private byte[] mBuffer;这个属性不见了,取而代之的是private final long mNativePtr;,其指向的是native的内存地址。为什么呢?

安卓的每个APP都是运行在单独的虚拟机中的,系统同时会有多个APP同时运行,所以分给每个虚拟机内存上限不会太高,一般也就几百M,虚拟机启动时内存上限就是定值,一旦达到内存上限,就会OOM。

但是安卓手机的可用内存普遍已经4、6、8个G,大多数情况下系统还是有剩余内存可用的(其他APP远没有达到自己虚拟机内存上限的情况下),而一个APP中占用内存最多的一般都是Bitmap,所以如果能把系统空余内存空间利用起来,就能大大增加当前APP的可用内存,而把bitmap的像素数据放到native就能解决这个问题,native可以直接使用整个linux系统的内存,不受当前APP所在虚拟机的内存上限控制,这样就可以持续使用内存,直到用完系统的空余内存。这样的坏处是一旦发生OOM,不会被系统的UncaughtExceptionHandler捕获,会直接crash。

不过借鉴之前经验,Bitmap引入了NativeAllocationRegistry这样一种辅助自动回收native内存的机制,依然不需要用户主动回收了,当bitmap的Java对象被回收后,NativeAllocationRegistry辅助回收这个对象所申请的native内存。

参考

Android Bitmap变迁与原理解析(4.x-8.x)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/121303.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 网页性能优化之图片懒加载

    一、前言最近因为需要做一个小网站,但是呢,因为图片比较多,打开网页速度很慢,服务器压力就会很大。不仅影响渲染速度还会浪费带宽,比如一个1M大小的图片,并发情况下,达到1000并发,即同时有1000个人访问,就会产生1个G的带宽。于是就想到了图片懒加载来减轻服务器的压力,优先加载可视区域的内容,其他部分等进入了可视区域再加载,从而提高性能,可以大幅度的提高网页加载速度,效果很明显,于是想着将这个方…

    2022年4月8日
    44
  • mmc卡和sd卡区别「建议收藏」

    mmc卡和sd卡区别「建议收藏」转载:https://zhidao.baidu.com/question/296690750.html区别:1、尺寸不同:SD卡的技术是基于MultiMedia卡(MMC)格式上发展而来,大小和MMC卡差不多,尺寸为32mmx24mmx2.1mm。长宽和MMC卡一样,只是比MMC卡厚了0.7mm,以容纳更大容量的存贮单元。2、兼容性不同:SD卡与MMC卡保持着向上兼容,…

    2022年6月11日
    37
  • 前端代码自动生成器「建议收藏」

    前端代码自动生成器「建议收藏」场景1.CodeFun是什么CodeFun是一款UI设计稿智能生成源代码的工具,支持微信小程序端、移动端H5和混合APP,上传Sketch、PSD等形式的设计稿,通过智能化技术一键生成可维护的前端代码.2.学习成本高吗?对于前端工程师来说,几乎没有学习成本。对于用惯了蓝湖/摹客的前端工程师来说,CodeFun使用流程与前者几乎一致:设计师上传完稿件后,工程师打开界面,选择任意需要的UI区域拷贝走想要的代码即可,只是从原来看标注变成了直接拷贝代码。对于设计师来说,完全不需要遵循某些设计规范

    2022年6月29日
    117
  • SFM综述

    SFM综述https://blog.csdn.net/qq_29462849/article/details/118159269

    2022年6月20日
    62
  • 新手入侵笔记_探灵笔记适合新手的角色

    新手入侵笔记_探灵笔记适合新手的角色【拿shell】 1.直接上传aspasajspcerphpaspxhtrcdx格式的木马,不行就利用IIS6.0解析漏洞”:1.asp;1.jpg/1.asp;.jpg/1.asp;jpg/1.asp;.xls 2.上传图片木马遇到拦截系统,连图片木马都上传不了,记事本打开图片木马在代码最前面加上gif89a,一般就能逃过拦截系统了。 3.上传图片木马把地址复制到…

    2022年9月21日
    5
  • document.getelementbyname_background-size:contain

    document.getelementbyname_background-size:containAttributes.Add()Attributes.Remove()Style.Add()Style.Remove()

    2022年9月25日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号