标签:匿名内部类 inf ati toc 分类 地图 首页 rev 代码
1. 内存性能评估
应用包(debug版)体积偏大,存在较多的内存泄露、OOM隐患、UI层级过深等问题,同时存在较多的其他各种内存问题。
应用apk包体积约50MB,安装到手机后,占用手机约99.50MB存储空间,运行时占用内存空间约160MB的内存空间,其中Native内存占用约65MB,Dalvik内存占用约6MB,从目前的业务复杂度分析,99.50的存储空间过于浪费,后续优化应针对apk降size,减小包体积。本次分析主要针对内存泄漏和OOM两大类内存问题进行分析,应用目前存在比较多的内存泄漏和OOM隐患。
内存泄露问题主要分布在(匿名)内部类/Callback间接持有Activity引用、Handler泄漏、static成员泄漏是项目工程中三块主要的内存问题,在本次发现内存问题总数中占比约55%。
OOM问题隐患主要分布在Bitmap未及时释放,在本次发现内存问题总数中占比约38%。
有些UI界面层级多达18层。
2.内存使用分析
本项分析的目的,在于概览应用在使用过程中占用内存的概况,从总体角度了解应用耗用内存的程度,大概在哪些地方耗用内存。
表1 描述了应用数据使用概况,应用安装后的大小为99.50MB,持久化数据存储空间占用空间量级在数MB左右。
表1 应用数据使用统计
编号 |
应用场景 |
应用大小(MB) |
数据大小(MB) |
1 |
安装完毕,立即查看应用数据占用 |
99.50 |
0.04 |
2 |
操作应用一段时间 |
99.50 |
1.36 |
3 |
紧接第2项,静置约60分钟后 |
99.50 |
1.53 |
4 |
紧接第2项,静置约240分钟后 |
99.50 |
1.53 |
表2描述了市面上常用大型成熟应用大小统计,从中可看出本应用的体积存在很大的压缩空间。
表2 大型成熟应用大小统计
编号 |
大型成熟应用 |
应用大小(MB) |
应用版本 |
1 |
今日头条 |
87.14 |
6.8.5 |
2 |
手淘 |
162 |
7.11.20 |
3 |
唯品会 |
173 |
6.25.3 |
4 |
微信 |
185 |
6.7.2 |
5 |
高德地图 |
214 |
8.61.1.1456 |
此项主要分析应用业务占用内存的概况,以一条比较占用内存的业务操作路径为例, 表3展示了应用业务的内存占用情况。
从表3可知,应用的内存占用总大小在155~160MB间,其中占用Native约60多MB的空间,而Dalvik空间占用约5.7MB左右,近50%的内存占用来自Native。
表3 应用内存使用统计(参考)
编号 |
总大小(MB) |
Dalvik(MB) |
Native (MB) |
1 |
123.13 |
5.76 |
62.88 |
2 |
156.17 |
5.38 |
61.25 |
3 |
159.44 |
5.78 |
62.97 |
4 |
159.20 |
5.63 |
61.09 |
附注:内存检测路径: 首页->音箱->在线音乐->歌单详情
表2中第1次的测试数据同另外3次测试数据有较大的差异,表3描述了这个差异的来源。
表4 导致表3数据较大差异来源
编号 |
.so mmap(MB) |
GL mtrack(MB) |
1 |
8.66 |
10.50 |
2 |
12.80 |
38.01 |
3 |
12.85 |
39.63 |
4 |
12.79 |
38.54 |
3. 内存泄露分析
历史内存泄露问题单共10例,问题原因主要集中在非静态内部类实例、匿名内部类实例、Callback实例直接/间接引用局部Context这几种情况。
历史问题单链接如下:
http://jira.evergrande.me/browse/IOT-7792
http://jira.evergrande.me/browse/IOT-7791
http://jira.evergrande.me/browse/IOT-7219
http://jira.evergrande.me/browse/IOT-7019
http://jira.evergrande.me/browse/IOT-6672
http://jira.evergrande.me/browse/IOT-5887
http://jira.evergrande.me/browse/IOT-5886
http://jira.evergrande.me/browse/IOT-5826
http://jira.evergrande.me/browse/IOT-5779
http://jira.evergrande.me/browse/IOT-4441
本次内存分析,共处理42例内存问题,分别如下:
5个内存问题JIRA单;
lint性能检查9个handler内存泄露、1个在onDraw内分配内存、1个cursor未recycle、7个static成员泄露;
代码Review检查2个Callback内存泄露、13个Bitmap未即时释放、2个Drawable重复内存申请;
工具检查1个Activity泄露;
开发群上报1个Activity has leaked window内存泄露及崩溃。
表5对本次发现的内存问题进行了分类汇总,内存泄漏问题38例,OOM问题1例,其他内存问题13例。
表5中的内存泄漏共38例,其中包括13例Bitmap未即时释放,原则上Bitmap未即时释放不是内存泄漏,但考虑到Bitmap是内存消耗大户,中短时间内得不到释放,极容易导致OOM,故本分析文档将Bitmap未及时释放归纳为内存泄漏门类。
在本次对内存的分析中,实际发现的Bitmap未及时释放的问题数远不止13例,因后续实施了问题补救措施——引入LruCache与OSS构建二级缓存,所以相当一部分的Bitmap没释放的问题点可暂时忽略。
表5 内存问题统计表
编号 |
检查类型 |
内存泄漏 |
OOM |
其他内存问题 |
1 |
JIRA单 |
4 |
1 |
|
2 |
lint检查 |
17 |
|
1 |
3 |
代码Review检查 |
15 |
|
2 |
4 |
工具检查 |
1 |
|
|
5 |
开发群上报 |
1 |
|
|
合计 |
|
38 |
1 |
3 |
图1描述了内存泄露问题分布,从中可分析出Handler泄漏、Bitmap未及时释放、static成员泄漏是项目工程中三块主要的内存问题,占比约85%。
图1内存泄露问题分布图
图2描述了各阶段上报的内存问题数,从中可分析出在编码阶段,更容易发现内存问题。
图2各阶段上报内存问题数
基础业务模块采用LruCache与OSS加载Bitmap,而设备模块采用Glide管理Bitmap,v1.1版本存在两个图片管理框架,后期需合并为一个图片管理框架。
项目代码中还存在经图形变换/未经缓存框架产生的Bitmap,没有及时释放。
应用中存在大量Callback,这些Callback的实现当中,不排除有为数不少的内存泄露隐患,绝大多数都和Activity等局部Context存在引用关系, 建议采用加入消息机制以杜绝此类内存泄露隐患。
本次内存优化,由于时间因素,以及项目UI界面需重新适配,故本次内存优化只是检查了UI层级嵌套情况,并没有对UI层级嵌套进行优化。
图3描述了较复杂页面及对应的UI层级,图3左边为实际展示的UI界面,图3右边为左边UI的UI层级,从中可看出图3的UI层级不低于18层级。
注意:图3中的层级从第4层开始算起,前面3层为系统生成的固定UI层级。
图3较复杂页面及对应的UI层级
图4描述了较简单页面及对应的UI层级,从中可看出图4的UI层级为7层。
图4简单页面及对应的UI层级
4.总结
本次内存分析,解决了一定量的内存泄漏和OOM隐患,但应用内还是存在为数不少的内存泄漏点和OOM隐患,要进一步解决内存问题,需要普及内存优化知识和观点,避免在新开发的模块功能埋入内存隐患,同时持续地对内存使用追踪和优化。
标签:匿名内部类 inf ati toc 分类 地图 首页 rev 代码
原文地址:https://www.cnblogs.com/tgltt/p/9554481.html