张绍文android开发高手课读书笔记2-内存优化篇
本系列博文 基于是前微信高级工程师张绍文专栏 《Android开发高手课》的读书笔记。
文章所写内容是本人读完的感悟,需要原文的朋友请自行购买。
内存优化篇
写在开头.
越读张老师的课,越会发现有很多知识完全没有接触过,课程的留言下方也有很多人反应说课程有点深。
秉持着"大家好才是真的好"的理念,之后的笔记都会记录一些大家容易理解的内容,
至于有些设计比较深的内容,一笔带过。有兴趣的朋友可以自行了解。
手机运行内存(RAM)作为 App 运行过程中临时性数据暂时存储的内存介质,因为体积和功耗的原因,没有直接采用PC上DDR的架构,而是该用LPDDR,可以理解为Lower PowerDDR.
内存不足所带来的问题
1.异常:其中异常包括OOM、内存分配失败这些崩溃,也包括因为整体内存不足导致应用被杀死、设备重启等问题。
2.卡顿:Java 内存不足会导致频繁 GC,而GC便会引起卡顿,这个问题在Dalvik 虚拟机比较明显,而ART虚拟机在内存管理跟回收策略上都做大量优化,所以卡顿现象没那么严重。
如果想要测试GC的性能,可以通过adb命令获取ANR日志.
//adb 命令
adb shell kill -S QUIT PID
adb pull /data/anr/traces.txt
//ANR日志
sticky concurrent mark sweep paused: Sum: 5.491ms 99% C.I. 1.464ms-2.133ms Avg: 1.830ms Max: 2.133ms // GC 暂停时间
Total time spent in GC: 502.251ms // GC 总耗时
Mean GC size throughput: 92MB/s // GC 吞吐量
Mean GC object throughput: 1.54702e+06 objects/s
除了频繁GC会造成卡顿之外,物理内存不足时系统会触发low memory killer 机制,进而影响手机性能。
关于物理内存不足引起的卡顿现象,不只发生在android系统上,最近笔者的苹果手机也因为物理内存不足,卡顿现象明显。
内存优化的两大误区
1.内存占用越少越好
有些朋友在内存优化的时候,总是觉得内存占有越低越好,实则不然。
假设手机的内存无限大,所有界面图片都不需要回收,这时你切换界面就能达到秒加载的体验.这种体验自然是最好的。
当然内存无限大是不存在的,但也反应了一点,内存使用高的时候性能会更好。
我们应该秉承着“用时分配,及时释放”的理念来优化内存。
2.Native内存不用管
在说Native内存之前,先来谈一谈常见的OOM。
Android系统会给每一个进程分配一个最大java堆.如果该进程申请的空间超过这个阈值时,就会抛出OOM异常。
所以程序发生OMM并不表示RAM(物理内存)不足
这样设计的目的是为了让Android系统能同时让比较多的进程常驻内存(RAM)。
Native内存起到什么作用?
拿常见的例子来说明,大家都知道android的内存大户是bitmap,OOM出现也多是因为图片。
-
在Android3.0之前,Bitmap对象放在java堆中,具体的像素数据放在Native中,这样做OOM的几率小了,但在图片回收的时候,不一定能及时释放Native内存中的图片像素数据。
-
于是在Android3.0~Android7.0期间,将Bitmap 对象和像素数据统一放到 Java 堆中.这样做资源是能及时回收了,但是OOM的问题又出现了。
-
Android8.0系统又觉得将Bitmap像素数据放回到Native中,只是这时多了一个NativeAllocationRegistry来帮助Native内存的回收。
那么8.0系统之后的手机性能优化对图片部分是不是就没有那么必要了呢?毕竟图片像素数据放入到Native之后就不太会引起OOM。
当然也不是,虽说OOM的几率小了,但没有回收的图片依旧占用着RAM,当RAM不够的时候,手机会开启
low memory killer 杀戮模式,后台,桌面,服务,前台,直至手机重启。
所以该回收的内存还是得回收的,如果因为手机内存不足导致手机卡顿,删点图片,腾出点空间还是有效果的。
java内存和Native内存的测量方法
java内存测量
- Allocation Tracker
- MAT
Native内存测量
- Chromium 的AddressSanitize
- 调试本地内存使用
如何着手内存优化
-
设备分级或者说内存分级
简单来说就是高内存,新手机效果全开.老爷机便宜货保留基本功能。
device-year-class是facebook开源的一个库.该库会根据手机的内存,CPU核心数和频率
得出手机属于那个年份。
而我们也可以根据这个年份来判断,效果全开还是保留基本功能。
补充部分:
-
一个空进程也会占用10MB的内存,所以对于一些低端机就不要开太多进程了
-
安装包中的代码、资源、图片以及 so 库的体积,跟他们占用的内存有很大关系。
所以apk优化还是有必要的。
-
-
Bitmap优化
统一图片库,主要是为了统一图片的调用入口.内存不足的时候可以降低图片格式,选用更合理的缩放算法。
另外一点,张老师在课中提到需要做图片监控,一般为了针对大图片和重复图片。(关于这方面,我也接触的不多,就不误导大家了。)
-
内存泄漏
内存泄漏主要分两种情况,一种是同一个对象泄漏,还有一种是每次都会泄露新的对象。
- Java 内存泄漏, 可以参考LeakCanary
- OOM监控 可以看看美团的Probe
- Native内存监控 微信 Android 终端内存优化实践
最后,给自己公众号打个广告,【码农的唠叨】聊技术,聊热文,聊互联网趣事,也发唠叨
![](https://img.haomeiwen.com/i1604627/76a067a1d68e86a7.jpg)