[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)

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 谈谈数据库连接池的原理及应用_常用的数据库连接池

    谈谈数据库连接池的原理及应用_常用的数据库连接池这次我们采取技术演进的方式来谈谈数据库连接池的技术出现过程及其原理,以及当下最流行的开源数据库连接池jar包。

  • Android 原生系统,手机rom下载网站

    Android 原生系统,手机rom下载网站Android,原生系统,手机rom,下载网站

  • PKI体系及常见证书

    PKI体系及常见证书http://blog.chinaunix.net/space.php?uid=23637692&do=blog&id=30579881.PKI体系1.1PKI(PublicKeyInfrastructure,公钥基础架构)PKI是一套以公钥技术为基础、提供安全服务的架构,由认证机构(CA),数字证书库,密钥备份和恢复,证书作废系统,应用接口等组成。CA是PK

  • Matlab矩阵操作[通俗易懂]

    Matlab矩阵操作[通俗易懂]第一部分:矩阵基本知识矩阵是进行数据处理和运算的基本元素。在MATLAB中a、通常意义上的数量(标量)可看成是”1*1″的矩阵;b、n维矢量可看成是”n*1″的矩阵;c、多项式可由它的系数矩阵完全确定。一、矩阵的创建在MATLAB中创建矩阵有以下规则:a、矩阵元素必须在”[]”内;b、矩阵的同行元素之间用空格(或”,”)隔开;c、矩阵的行与行之间用”;”(或回车符)隔开;d、矩阵的元素可以是数值、变量、表达式或函数;e、矩阵的尺寸不必预先定义。下面介绍四种矩阵的创建方法:

  • What is Observer and Observable and when we used these?

    What is Observer and Observable and when we used these?

  • 不是单组分组函数

    不是单组分组函数问题:一:SELECT tablespace_name, SUM(bytes) freeFROM dba_free_space不是单组分组函数原因: 1、如果程序中使用了分组函数,则有两种情况可以使用:程序中存在group by,并指定了分组条件,这样可以将分组条件一起查询出来改为:  SELECT tablespace_name, SUM(bytes) freeFROM dba_free_spa…

发表回复

您的电子邮箱地址不会被公开。

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