腾讯技术分享:Android版手机QQ的缓存监控与优化实践
admin 发布:2024-11-22 03:07 10
《》
《》
《》
《》
《》
《》
《》
《》
3、统一缓存监控
统一缓存监控主要包含图片缓存监控和业务对象缓存监控两部分:
1)图片缓存监控主要关注Bitmap的引用,定位图片问题;
2)业务对象缓存监控,主要监控手Q各业务对象缓存,及时发现缓存问题。
3.1图片缓存监控
对于Android应用来说,Bitmap向来是内存的占用大户。在手Q中平均有300+ Bitmap对象。
统计显示:Bitmap引用内存占手Q总内存40%左右:
减少图片占用内存,需要规范图片缓存的使用。前期我们在手Q中封装实现了图片专用多级缓存QQLruChe,并要求各业务必须使用全局图片专用缓存来缓存图片。一方面可以方便调控图片缓存业务,另一方面,通过淘汰以及清理策略,可以有效控制图片缓存大小。但由于手Q业务众多,业务独立开辟图片缓存的情况还是时有发生。因此我们开发了一套图片缓存监控系统,及时检测出图片缓存私藏问题,同时也监控图片的其他不合理使用。
图片缓存监控使用内存快照技术实现,分为终端数据采集和后台数据分析两部分。
流程如下所示:
终端数据采集:客户端实时检测当前可用内存,当可用内存不足时,自动生成内存快照文件,上报到后台。
后台数据分析:在后台,我们实现了一套Hprof文件分析以及Bitmap引用归并技术,批量分析内存快照文件,输出Bitmap引用链并进行归类统计,过滤全局图片专用缓存以及View层引用后,分析出存在图片缓存私藏的业务。
实现图片缓存监控过程中我们主要遇到以下几个难点:
1)内存快照文件大,约300M左右:
内存文件过大会导致上传流量和存储成本比较大,而且上传耗时长。针对这个问题,一方面,我们对大盘用户采样上报,并提供良好的用户交互。另一方面我们深入分析内存快照采集原理,自研miniDump工具,通过native hook技术在生成内存快照时剔除了tyte[]数据,从而使文件体积减少70%;
2)内存快照文件人工分析成本高:
通过MAT人工分析内存快照文件耗时费力,而且分析数量有限,用户上报的内存文件很多,无法定位top问题。针对该问题,我们深入研究MAT插件技术,自研引用链分析以及Bitmap引用归并工具,自动化分析内存快照文件,归类Bitmap图片引用。
通过图片监控系统,我们有效检测出以下几类业务问题:
1)全局图片专用缓存占用空间大,存在优化空间:
bitmap引用链归并发现全局图片专用缓存占较高。同时,我们也统计了OOM用户全局图片缓存的内存量,平均约10M左右。因此有必要在内存不足时,自动trimToSize,释放内存空间;
2)业务bug——逻辑完成后,没有及时释放图片引用:
业务逻辑存在问题,比如有几类业务在页面退出后,没有及时释放背景图资源引用;
3)业务私自开辟图片缓存:
业务独立开辟缓存cache缓存bitmap,没有使用全局图片专用缓存;
4)业务缓存数据对象中引用图片:
业务内存缓存的数据对象中,含有bitmap成员,内存空间大。可优化为缓存key,bitmap对象存到全局图片专用缓存中;
5)图片静态引用:
定义静态的Bitmap或者Drawable对象,进程周期内,对象所引用的资源都无法释放。
在手Q730版本,图片缓存监控系统检测出32例业务问题,提单26例,累计节省内存约23M。
3.2业务对象缓存监控
业务对象缓存监控主要是通过实现自定义集合类,实时上报各业务内存缓存使用情况到后台。在后台分析归并,从而定位业务缓存问题。
如上图所示,业务对象缓存主要分为终端数据采集、后台数据分析、缓存清理三部分:
终端数据采集:通过自定义实现QQHashMap,QQConCurrentHashMap,QQLruCache等集合类,在系统原有集合类基础上,封装统计功能,实时统计程序运行期间各缓存的内存指标:插入次数,查询次数,删除次数,遍历次数,命中次数,未命中次数,缓存使用率,内存占用等;
后台分析:分析终端上报的用户数据,对各业务缓存进行归类统计,统计出平均内存占用,最大内存占用,内存占用中位数,缓存命中率,缓存浪费率等指标;
内存清理:监控系统在监控的基础上,也增加了清理接口。当检测到当前可用堆内存比较低,用户处于内存高负荷状态时,统一调度清理逻辑,进行内存自清理优化。
通过统一缓存监控,我们检测出了很多业务缓存问题,主要可归为以下三类。
1)缓存浪费率高:
典型案例1:手Q表情某类缓存,平均浪费率超过88%,相当于缓存1000个对象,有800+没有使用过;
典型案例2:某红包模板缓存,存储后从不访问,浪费率100%。
针对这类问题,推动业务优化内存缓存结构,去除无用缓存,优化缓存方案,以降低浪费率。
2)缓存内存占用大:
典型案例1:手Q某新闻类图片缓存,私自缓存Bitmap,最大占用内存15M,占所有图片缓存的35%;
典型案例2:钱包类背景图缓存,内存占用约1M左右,使用后未及时释放。
针对这类问题,对于缓存图片的业务,推动业务接入全局图片专用缓存;对于非图片类业务,接入自动清理,及时释放内存空间。
3)缓存结构存在优化空间:
典型案例1:讨论组成员缓存,设计为LRUCache可淘汰缓存,但是用户未曾用满过。初始开辟空间过大;
典型案例2:未读消息缓存,极端用户缓存个数超过9000个,无数量上限控制。
针对这类问题,推动业务更新或者优化缓存结构,增加上限控制等。
4、内存清理
统一监控,可以有效发现业务缓存问题进行专项优化。但监控具有一定的滞后性,因此在监控的基础上,我们同时也增加了内存清理控制模块。
内存清理主要分为业务内存清理以及系统内存清理。业务内存清理,包含统一图片缓存清理,以及业务缓存对象清理两部分。这里前文已简单介绍。接下来我们介绍下两例系统相关的内存清理技术:系统ClassLoader内存清理和系统预加载图片清理。
4.1系统ClassLoader内存清理
前期,我们分析了很多内存快照,发现一个共性的问题:在内存快照中有个ZipFile对象,内存占用一直超过2.6M。这个zipFile被系统类ClassLoader引用。
通过分析系统源码,我们发现ZipFile记录了安装包所有的类文件信息,手Q安装包中有超过15000个文件,文件越多,zipFile占用内存就越大。
我们进一步分析ClassLoader相关源码,发现只有在调用ClassLoader的findResource方法查找图片等安装包内资源时,才会使用到ZipFile的内容,未发现其他使用场景。同时,通过findResource方式查找资源存在一定的弊端:耗时很长,在Android系统上不推荐使用。
详情分析可参考:
综合评估,可以清理ClassLoader引用的这块内存。
清理主要面临以下几个难点:
1)Android系统碎片化严重,兼容性问题比较突出:
不同版本,zipFIle成员变量的位置以及变量名不同。zipFile初始化时机改变:4.3以前创建时即初始化,4.3之后,第一次访问才会初始化。各厂商对系统API内部修改无法预期;
2)强行清理,可能导致功能异常:
系统内部代码逻辑可能会受到影响,而且影响无法预期。手Q当前使用ClassLoader查找资源的业务功能会受到影响。后期新增业务无法预期,清理会导致系统功能失效;
3)清理后再次加载zipFile耗时长,可能导致卡顿。
下图是我们清理系统ClassLoader的实现方案,采用代理,兜底,缓存,上报等手段逐一攻克以上难点,完美实现清理系统ClassLoader内存的效果。
1)针对兼容性问题,我们通过反射代理替换了系统的ZipFile为HookZipFile,替换完成后,清理掉zipFile内存。替换机制兼容系统不同版本以及特殊机型,对系统逻辑无影响。
2)针对清理导致的功能异常,我们实现了兜底能力,下次访问时,会重新创建zipFile。
3)针对耗时问题,内部封装实现缓存功能。并针对业务访问增加堆栈上报,及时推动业务改用其他方式获取资源。
内存清理方案,通过内部兼容性测试,发布后外网无crash问题,通过不断迭代,兼容率达到100%。并且内存清理效果明显,平均清理内存量约2.6M。
4.2系统预加载图片清理
系统预加载图片缓存是zygote进程初始化时,通过preloadResources()预加载的通用图片资源,后续android应用进程都是从Zygote fork出来的,所以就继承了这部分预加载的图片资源。由于是静态强引用,这部分图片资源会一直占用内存空间。
预加载的好处在于系统只在zygote执行一次加载操作,所有应用用到该资源不需要再重新加载,减少资源加载耗时。与此同时,sPreloadedDrawables属于静态对象,会一直引用图片缓存,所以该系统机制会占用较高内存,在有些系统上,内存占用空间超过20M。
因此这里存在内存优化的空间,当内存占用高时,可以主动清理掉这部分内存,以便释放可观的堆内存空间,减少内存耗尽的风险。通过分析drawable加载机制的源码,我们了解到如果预加载的资源没有在sPreloadedDrawables中找到,会重新decode解码加载,不会影响现有功能。
因此清理后的风险可控,主要面临的难点是兼容性问题:
1)系统API变动较多:
sPreloadDrawables数据结构类型,对象存储位置,不同API版本之间都有改动;
2)厂商自定义修改较多:
比如:小米7.0系统以及华为部分机型各自扩展了ResourceImpl实现,自定义了自己的资源加载基类,导致无法定位到sPreloadDrawable;OPPO部分机型,修改了sPreloadDrawable类的属性等等。
下图是我们清理系统预加载图片缓存的实现方案,通过反射替换的方式,拦截替换系统的预加载缓存为自定义图片缓存,内部管理图片加载,在内存不足时,及时清理预加载图片缓存。
针对兼容性问题,我们实现了一套完备的兼容性方案:
1)替换前兼容检测;
2)系统版本兼容处理;
3)特定机型兼容处理;
4)失败上报统计,不断兼容。
系统预加载图片清理,通过不断迭代,已经可以兼容几乎所有机型。版本发布后,未引入系统功能异常以及外网crash问题。内存清理量比较可观:平均在15M左右,最高达到25M。
5、优化后的效果
5.1横向对比
在灰度阶段,我们对用户进行了ABTest测试,一半用户接入内存优化逻辑,一半用户不接入。大盘上报统计显示:优化用户OOM率明显低于未优化用户:OOM率由0.09%降至0.053%。
内存分布方面,内存优化显著降低了高内存用户占比。由3.05%降至1.7%。高内存用户是指当前可用内存不足20%的用户,是OOM高发用户群,降低这部分用户比例,可有效降低OOM率。
5.2纵向对比
我们从7.3.0版本接入内存优化,从版本迭代来看,优化效果显著:OOM率由0.09%左右降低至0.047%左右,降幅47%:
手Q版本间平均内存增幅明显放缓,版本增幅由5.8M左右降至1.14M左右:
- 上一篇: 薅羊毛活动最全集合地址?最新羊毛活动更新渠道
- 下一篇: qq豪华蓝钻怎么刷永久
推荐应用
相关推荐
- 11-25羊毛活动|中行80元、翼支付权益金、工行美好星期五、交通最红星期五、建行两个立减金活动
- 11-25腾讯视频会员升级到V6要多久大概多少钱?
- 11-25京东薅羊毛活动指南,1折买东西不是梦!
- 11-25会员能成为长视频的商业营销增量吗?
- 11-25羊毛活动|兴业支付宝红包、邮储红包雨、云闪付5元支付券、8折生活缴费
- 11-25影视VIP会员(原钻石会员)
- 11-25美姑县第二届剪羊毛节活动掠影
- 11-25一文集齐常用会员开通方式,不求最全,但求最值,帮你省流省事省钱!
- 11-25薅羊毛是什么意思「简单易懂」
- 11-25祝愿LZ使用QQ会员和QQ快乐,这些特权很好滴喽
热门下载
-
1
2022百度网盘安卓版突破限速
类别:手机软件
-
2
免费领QQ超级会员助手
类别:QQ软件
-
3
抖音视频自动评论助手——养号必备
类别:手机软件
-
4
亲测可用的微信视频号下载器,内含详细教程
类别:电脑软件
-
5
和平精英捏脸助手v2.0
类别:QQ软件
-
6
视频字幕提取器怎么用?2023最新字幕提取工具 Video subtitle extractor 2.0.0
类别:电脑软件
-
7
酒店微型摄像头检测器-安卓版
类别:手机软件
-
8
抖音无水印解析批量下载pc版
类别:电脑软件
-
9
QQ动态个性名片—安卓版
类别:QQ软件
-
10
全网短视频无水印下载工具 支持tiktok
类别:电脑软件
-
11
2022最新版qq透明头像生成软件
类别:QQ软件
-
12
安卓魔音变声器青春版v2.1.3
类别:手机软件