Android性能优化(二)—— 内存优化
在Android
系统中,垃圾回收是自动的,比较隐蔽,这就导致一些内存问题表现的并不明显,出现问题后难以定位。常见的内存问题有内存泄漏、内存溢出(Out of Memory
)、内存抖动等。
我们做内存优化的主要原因有以下几点:
- 降低
OOM
率,内存问题最常见的就是OOM
,申请的内存得不到释放就有可能造成OOM
; - 减少卡顿, 在
Android
系统中造成卡顿的原因有很多,其中就有内存引起的卡顿。内存问题之所以会影响到界面流畅度,是因为垃圾回收机制,在GC
的时候,所有的线程都要停止工作,包括主线程。因此,当GC
和绘制界面的操作同时触发时,绘制的任务就会被搁置,导致掉帧,也就是界面卡顿; - 增加应用存活时间,
Android
系统会按照特定的流程清理进程,优先考虑清理后台进程,如果某个应用在后台运行且占用的内存很多,就会被优先清理掉。如果我们希望APP
可以存活的久一点,不使用的内存应该尽快清理掉;
至于哪些对象是需要回收的?使用跟搜索算法/可达性算法,选定一些对象作为GC Roots
,向下搜索,搜索所经过的路径称为引用链,当一个对象到GC Roots
没有应用链相连,则表明此对象需要回收。以下是可以作为GC Roots
的对象:
- 本地方法栈中引用的对象;
- 虚拟机栈中引用的对象;
- 全局静态变量引用的对象;
- 全局常量引用的对象;
Java虚拟机(四)—— Java虚拟机中的对象
1 内存泄漏
内存泄漏指的是我们的应用已经不需要某些对象了,但是,该对象的某些引用依旧没有释放,导致这些对象没有办法被回收。从内存上来看,就是某块内存已经不再被使用了,但是却没有办法被回收掉,从而造成了内存浪费。 比如说匿名内部类持有外部类的引用,导致外部类无法被回收,就会出现内存泄漏的问题。
内存泄漏会导致无法回收的内存越来越多,可用的内存越来越少,直到应用无更多可用的内存申请,严重的甚至出现OOM
。
内存泄漏
2 内存溢出(OOM Out Of Memory
)
内存泄漏一般导致应用卡顿,极端情况会导致OOM
,OOM
的原因是因为超过内存的阈值。原因主要有两方面:
- 内存泄漏,导致无法及时释放导致
OOM
; - 一些逻辑消耗了大量内存,无法及时释放或者超过导致
OOM
;
能够消耗大量内存的,绝大多数是因为图片加载。这是OOM
出现最频繁的地方。图片加载,一个是控制每次加载的数量,二是保证每次滑动的时候不进行加载,滑动完进行加载。一般情况使用先进后出,而不是先进先出。 不过一般我们图片加载都是使用fresco
或者Glide
等开源库。
下面是导致内存溢出的两种情况:
通过命令行查看内存消耗情况(adb shell dumpsys meminfo 包名 -d
):
对于图片的内存优化:
- 图片缩放,比如说一张图片的饿宽高为
200 x 200
,但是View
的宽高为100 x 100
,这个时候就要对图片进行缩放,通过inSampleSize
实现; - 减少每个像素所占用的内存,在
API 29
中,将Bitmap
分为ALPHA_8
、RGB_565
、ARGB_4444
、RGBA_F16
、HARDWARE
六个等级:ALPHA_8
:不存储颜色信息,每个像素占1
个字节;RGB_565
:仅存储RGB
通道,每个像素占2
个字节,对Bitmap
色彩没有高要求,可以使用该模式;ARGB_4444
:已弃用,用ARGB_8888
代替;ARGB_8888
:每个像素占用4
个字节,保持高质量的色彩保真度,默认使用该模式;RGBA_F16
:每个像素占用8
个字节,适合宽色域和HDR
;HARDWARE
:一种特殊的配置,减少了内存占用同时也加快了Bitmap
的绘制;
- 每个等级每个像素所占用的字节是不一样的,所存储的色彩值也不同,同一张
100
像素的图片,ARGB_8888
占用了400
字节,RGB_565
才占用200
字节。所以在某些场景中,修改图片格式也可以达到减少一半内存的效果。
内存复用,避免重复分配内存。Bitmap
所占用的内存比较大,如果频繁的创建和回收Bitmap
,很容易造成内存抖动,所以应该尽量复用Bitmap
内存。在Android 3.0(API 级别 11)
开始,系统引入了BitmapFactory.Options.inBitmap
字段。如果设置了此选项,那么采用Options
对象的解码方法会在生成目标Bitmap
时尝试复用inBitmap
,这意味着inBitmap
的内存得到了重复使用,从而提高了性能,同时移除了内存分配和取消分配。不过inBitmap
的使用方式存在某些限制,在Android 4.4(API 级别 19)
之前系统仅支持复用大小相同的位图,4.4 之后只要inBitmap
的大小比目标Bitmap
大即可 - 大图局部加载策略:对于图片加载还有种情况,就是单个图片非常巨大,并且还不允许压缩。比如显示:世界地图、清明上河图、微博长图等。首先不压缩,按照原图尺寸加载,那么屏幕肯定是不够大的,并且考虑到内存的情况,不可能一次性整图加载到内存中。所以这种情况的优化思路一般是局部加载,通过
BitmapRegionDecoder
来实现
上面所说的这些关于Bitmap
的内存优化策略其实都比较简单,而且我们在开发中可能很少用到
因为我们常用的图片框架比如Glide
已经将这些都封装在里面了,所以一般情况下我们加载图片时不需要做这些特殊操作。
3 内存抖动
在短时间内频繁的创建或者销毁的对象,容易触发GC
,会引起内存抖动,比如在一个for
循环中创建临时对象实例。
因为GC
的时候所有的线程都会停止工作,因此导致卡顿。为了避免内存抖动,应该避免以下操作:
- 尽量避免在循环体中创建对象;
- 尽量不要在自定义
View.onDraw()
方法中创建对象,因为这个方法会被频繁调用; - 对于能够复用的对象,可以考虑使用对象池把它们缓存起来;
参考
Android内存优化深入解析
关于android 性能优化——内存篇
Android性能优化——内存优化
Android性能优化(二)—— 内存优化相关推荐
- Android 系统性能优化(55)---Android 性能优化之内存优化
Android 性能优化之内存优化 前言 Android App优化这个问题,我相信是Android开发者一个永恒的话题.本篇文章也不例外,也是来讲解一下Android内存优化.那么本篇文章有什么不同 ...
- App性能优化(布局优化,线程优化,app瘦身优化,页面切换优化,App启动优化,内存优化)
Android APP性能优化(最新总结) 在目前Android开发中,UI布局可以说是每个App使用频率很高的,随着UI越来越多,布局的重复性.复杂度也随之增长,这样使得UI布局的优化,显得至关重要 ...
- Lua性能优化—Lua内存优化
原文链接https://blog.uwa4d.com/archives/usparkle_luaperformance.html 这是侑虎科技第236篇原创文章,感谢作者舒航供稿,欢迎转发分享,未经作 ...
- android—性能优化2—内存优化
文章目录 性能优化: 工具: memory profiler LeakCanary arthook epic 库 java内存管理机制 java 内存回收机制 Android内存管理机制 Dalvik ...
- Android性能优化之内存优化 1
导语 智能手机发展到今天已经有十几个年头,手机的软硬件都已经发生了翻天覆地的变化,特别是Android阵营,从一开始的一两百M到今天动辄4G,6G内存.然而大部分的开发者观看下自己的异常上报系统,还是 ...
- Android 性能监测工具,优化内存、卡顿、耗电、APK的方法
导语 安卓大军浩浩荡荡,发展已近十个年头,技术优化月新日异,如今 Android 9.0 代号P 都发布了,Android系统性能已经非常流畅了.但是,到了各大厂商手里,改源码自定系统,使得 ...
- Android面试-Android性能优化和内存优化、APP启动速度一线大厂的实战案例解析
一.Android 内存管理机制 二.优化内存的意义 三.避免内存泄漏 四.优化内存空间 五.图片管理模块的设计与实现 六.总结 深入探索Android内存优化 第一章.重识内存优化 第二章.常见工具 ...
- Android性能优化之内存优化浅析
一.背景 Android由于是以Java语言为主要开发语言,所以它的内存管理并不像C语言那样由开发者去管理内存的分配以及回收等,而是交由JVM虚拟机的内存回收机制去处理.这就导致我们在开发过程中难免会 ...
- Android App性能优化之内存优化
为什么要进行内存优化? 1.App运行内存限制,OOM导致App崩溃 2.App性能:流畅性.响应速度和用户体验 Android的内存管理方式 Android系统内存分配与回收方式 ● 一个App ...
- Android 系统性能优化(30)---Android性能全面分析与优化方案研究
Android 性能优化 1.结合以下四个部分讲解: 性能问题分类 性能优化原则和方法 借助性能优化工具分析解决问题 性能优化指标 2性能问题分类 1.渲染问题:过度绘制.布局冗杂 2.内存问题:内存 ...
最新文章
- 赠书 | 元宇宙:开启未来世界的六大趋势
- 编程 25 年后,现实将我打回菜鸟程序员的起点
- 【中间件】大数据之分布式消息队列Kafka
- MyBatis 架构分层与模块划分
- MSSQL优化之————探索MSSQL执行计划
- latex正文显示运算符
- 爱奇艺视频如何联系客服?爱奇艺联系客服攻略
- oracle表空间管理sql,oracle表空间管理维护
- linux上samba+本地yum源最简单的配置
- UE4之cmd调用函数
- mysql表添加字段_怎么给mysql数据表添加字段
- 【vivado使用】第2篇:超实用的vivado使用教程
- 最稳定的tracker服务器,BT Tracker服务器
- copyonwritearraylist 深究
- Identifying Antioxidant Proteins by Using Optimal Dipeptide Compositions论文笔记
- 与rasp的初次心动
- 画坦克__坦克可移动
- 嵌入式开发有必要学习python吗?
- 分割 fasta 文件
- 国产Linux系统UOS安装
热门文章
- 炒币机器人:囤币,我们是“一囤到底”还是“半路抛弃
- 什么是软件需求,什么是功能需求?——论需求的三个层次和三个方面(2)
- 原创| Python中“等于“到底用 == 还是 is ?
- wincc7.2安装授权的时候,该安装哪些?
- 802.1x身份验证
- spring日志加载代码解析
- 【大有用处】步进电机的选型计算方法
- screenshot python_python 截图screenshot处理
- 基于光电检测图像处理目标检测算法相较传统检测技术的优势
- 【学术相关】清华教授发文劝退读博:​​我见过太多博士生精神崩溃、心态失衡、身体垮掉、一事无成!...