请选择 进入手机版 | 继续访问电脑版

[Android] 详解Android内存优化策略

[复制链接]
查看125 | 回复41 | 2021-9-14 06:42:57 | 显示全部楼层 |阅读模式
目次

前言

在开始之前必要 先搞明确 一个标题 ,为什么要做内存优化?或者说做内存优化的目标 是什么?

一、内存优化策略

内存优化一样平常 从两个方向动手 优化,一方面就是上篇博客写的防止内存走漏 ,避免不必要的内存资源浪费;另一方面就是APP中大对象的优化,减小大对象占用的内存。

二、详细 优化的点

1.避免内存走漏

这里直接看上篇博客就行:
详解Android内存走漏 及优化方案

2.Bitmap等大对象的优化策略

图片加载算是内存占用的罪魁祸首,而且也是最常见的,以是 优化bitmap的占用内存是很关键的。
Bitmap的内存计算公式如下:

  1. Bitmap占用内存 = 分辨率 * 单个像素点的内存
复制代码

比如说一个 1920 * 1080 的图片,它所占用的内存就是1920 * 1080 * 单个像素点内存。因此,对于Bitmap的优化就可以从分辨率和单个像素点两个方面来举行 优化。

(1) 优化Bitmap分辨率

通常APP加载一张图片时间 ,ImageView的大小是确定的,比如一个ImageView的大小设置为 100 * 100 ,但是被加载的Bitmap的分辨率是 200 * 200,那么就可以通过采样压缩将该 ‘Bitmap' 的分辨率压缩到 ‘100 * 100'。通过这一压缩操作可以直接减少4倍的内存大小。代码如下:

  1. val options = BitmapFactory.Options()
  2. options.inSampleSize = 2 // 设置采样率为2,则会每两个像素点采一个像素,最终分辨率宽高变为原来的 1/2
  3. val bitmap = BitmapFactory.decodeResource(resources, R.drawable.image, options)
复制代码

(2) 优化单个像素点内存

计算机中的图像一样平常 都是由 红、绿、蓝 三个通道加上一个透明通道构成 的,因此一个像素点也是由红、绿、蓝,以及一个透明通道构成 ,对应到内存就是通过byte来表示,比如用2个 byte 来存储一个像素点,那么每个通道就占用 4 bit 的内存,而假如 用 4 个 byte 来存储一个像素点,那么每个通道就占用 1 个byte。4 字节的像素点,相比2字节的像素点可以表示的色彩会更加丰富,因此四字节的像素点构成 的图像质量也更加清楚 。(一个Byte由8 bits构成 ,是数据存储的基础单位,1Byte又称为一个字节)

在 Android 的 Bitmap 中单个像素点占用的内存与 Bitmap 的 inPreferredConfig 参数设置 有关系,代码设置如下:

  1. final BitmapFactory.Options options = new BitmapFactory.Options();
  2. options.inJustDecodeBounds = true;//只解析图片边沿,获取宽高
  3. options.inPreferredConfig = Bitmap.Config.RGB_565;
  4. BitmapFactory.decodeFile(filePath, options);
  5. // 计算缩放比
  6. options.inSampleSize = calculateInSampleSize(options, desWidth, desHeight);
  7. // 完整解析图片返回bitmap
  8. options.inJustDecodeBounds = false;
  9. Bitmap bm = BitmapFactory.decodeFile(filePath, options);
复制代码

options.inPreferredConfig = Bitmap.Config.RGB_565;设置的参数如下表:

Config设置 占用内存(byte) 备注
ALPH_8 1 只包含一个透明通道,透明通道占用 8bit,即 1byte
RGB_565 2 包含R/G/B三个颜色通道,不包含透明通道,三个通道占用的内存分别为5bit/6bit/5bit
ARGB_4444 2 已废弃,包含A/R/G/B四个颜色通道,每个通道占用4bit
ARGB_8888 4 24位真彩色,Android默认设置 ,每个通道占用 8bit
RGBA_F16 8 Android 8.0 新增,每个通道占用16bit,即两个字节

在Android体系 中 Bitmap 的默认色彩模式为 ARGB_8888, 即每个像素占用了4byte,那么在默认环境 下,一张分辨率为1920 * 1080 的图片,加载到内存后占用的内存大小为1920 * 1080 * 4 = 7.91M

可以通过设置 inPreferredConfig 参数来设置对应的色彩模式,比方 ,一个不包含透明通道的图片,我们可以将其设置为RGB_565,即保证了图片的质量,又减少了内存的占用。
此时,一张 1920 * 1080 的图片加载到内存后的内存大小为 1920 * 1080 * 2 = 3.955M,比默认环境 下的内存占用减小了一半。

(3) Bitmap的缓存策略

通过缓存策略也可以肯定 程度上的优化内存占用标题 ,比如 Glide 框架中采用了三级本地缓存策略来实现Bitmap的优化,通过设置活动缓存、LRU内存缓存和本地缓存。对于雷同 参数的ImageView,在内存中只保存一份,以此来减少内存大小。

(4) drawable资源选择合适的drawable文件夹存放

比方 我们只在 hdpi 的目次 下放置了一张 100 * 100 的图片,那么根据换算关系,分辨率匹配到 xxhdpi 的手机去引用这张图片时就会被拉伸到 200*200。必要 留意 到在这种环境 下,内存占用是会明显 进步 的。对于不渴望 被拉伸的图片,必要 放到 assets 或者 nodpi 的目次 下。

(5) 其他大对象的优化

可以使用 更加轻量级的数据布局 。比方 ,我们可以思量 使用 ArrayMap/SparseArray 而不是 HashMap 等传统数据布局 ,相比起 Android 体系 专门为移动操作体系 编写的 ArrayMap 容器,在大多数环境 下,HashMap 都表现 服从 低下,更占内存。别的 ,SparseArray更加高效在于,避免了对key与value的自动 装箱,并且避免了装箱后的解箱。

(6) 避免内存抖动

内存抖动是指在短时间内忽然 创建大量的对象,频仍 的引发GC回收,造成内存波动的环境 。在开辟 中应该避免频仍 的创建对象,来避免内存抖动。由于 内存抖动会频仍 触发 GC,而GC又会引起 STW 标题 ,直接影响程序的性能。

比如在绘制自定义View的时间 肯定 要避免在onDraw或者onMeasure中创建对象。

3.原生API回调开释 内存

Android体系 提供了一些回调来关照 当前应用的内存使用 环境 ,比如下边的两个方法:

onLowMemory() 通常来说,当全部 的Background应用都被kill掉的时间 ,forground应用会收到onLowMemory()的回调。在这种环境 下,必要 尽快开释 当前应用的非必须的内存资源,从而确保体系 可以或许 继续稳固 运行。尤其是要开释 Glide中缓存的Bitmap资源,通过调用Glide.onLowMemory方法举行 资源回收。

onTrimMemory() Android体系 从4.0开始还提供了onTrimMemory()的回调,当体系 内存达到某些条件的时间 ,全部 正在运行的应用都会收到这个回调,同时在这个回调内里 会传递以下的参数,代表不同的内存使用 环境 ,收到onTrimMemory()回调的时间 ,必要 根据传递的参数范例 举行 判断 ,合理的选择开释 自身的一些内存占用,一方面可以进步 体系 的团体 运行流通 度,别的 也可以避免本身 被体系 判断 为优先必要 杀掉的应用。比方 调用Glide.onTrimMemory()来举行 bitmap的回收。

4.内存排查工具

(1)LeakCanary监测内存走漏

在debug模式下会不停 开着LeakCanary来检测内存走漏 标题 ,根据LeanCannary提供的引用连可以快速定位到内存走漏 的位置。

(2)通过Proflier监控内存

在一个功能开辟 完成后可以通过Profiler来检测APP的内存使用 环境 。反复的打开关闭页面,然后触发GC,内存是否可以或许 减少。

(3)通过MAT工具排查内存走漏

MAT提供了很强大 的功能,可以查看对象的深堆、浅堆的内存大小等。

总结

平常 开辟 对于这块的关注不是很多,大概 在没有出现内存不足的标题 前不会思量 这些,项目标 要求没有那么高,学习过这些点以后必要 在开辟 中逐步 关注这些标题 。

到此这篇关于详解Android内存优化策略的文章就先容 到这了,更多干系 Android内存优化内容请搜刮 脚本之家从前 的文章或继续欣赏 下面的干系 文章渴望 大家以后多多支持脚本之家!


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

avatar 厕层柴 | 2021-9-14 09:13:22 | 显示全部楼层
强,我和我的小伙伴们都惊呆了!
回复

使用道具 举报

avatar 甜心猫舍 | 2021-9-14 13:36:15 | 显示全部楼层
顶一下,收藏了!
回复

使用道具 举报

每天顶顶贴,一身轻松啊!
回复

使用道具 举报

avatar 换即势 | 2021-9-20 20:17:34 | 显示全部楼层
admin楼主,我告诉你一个你不知道的的秘密,有一个牛逼的源码论坛他的站点都是商业源码,还是免费下载的那种!特别好用。访问地址:http://www.mxswl.com 猫先森网络
回复

使用道具 举报

avatar Runlinh | 2021-9-21 13:29:59 | 显示全部楼层
灌水不是我的目的!
回复

使用道具 举报

avatar 当当当当裤裆坦 | 2021-9-22 12:17:29 | 显示全部楼层
admin楼主该去看心理医生了!
回复

使用道具 举报

avatar 网路游民甲厝 | 2021-9-25 18:50:07 | 显示全部楼层
大神就是大神,这么经典!
回复

使用道具 举报

avatar 郭光庆 | 2021-9-26 09:43:25 | 显示全部楼层
今天怎么了,什么人都出来了!
回复

使用道具 举报

avatar 执着294 | 2021-9-26 13:38:46 | 显示全部楼层
admin楼主很有艺术范!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则