专栏首页QAPM-腾讯客户端性能分析技术揭秘,QAPM的这位Android内存分析“专家”
原创

技术揭秘,QAPM的这位Android内存分析“专家”

祝大家新春快乐,技术干货来袭。不知道各位还记得许久之前分享过的Finder吗?记得我们在QQ的零人力内存测试的实践吗?之前的那个专家叫“Finder”,基于MAT改造,造就了许许多多的新功能,不过已经有点老了,LeakCanary都出2了,而且还用kottin重写,性能和功能都有了质的飞跃。对于有技术追求的我们,怎敢落后,至此,这位的内存分析专家已经融入到了我们的分析云之中。下面从技术角度我们来揭开这位技术专家的秘密。

背景,追赶QAPM的愿景

QAPM原有Android内存快照分析是基于那个颇具历史感的MAT的命令行版本开发的。MAT到现在都依旧是最最强大的内存快照分析工具,就是他那个类SQL的查询能力灵活性就已经甩很多工具N条街。但是我们是个基于大数据的监控平台,我们用大数据来帮助研发聚焦问题根因的愿景,MAT的数据处理性能明显赶不上我们。后面我们发现了开源项目LeakCanary的Shark Android Extension更新,虽然功能有点简单,能处理部分安卓内存泄露,很简单内存触顶分析模块,但是用kottin重写,传说性能是以前的3倍。为了让技术赶上我们的愿景,我们切换到了Shark。下面我们从两个维度来说说,我们基于Shark如何进一步地性能优化,功能上,我们对其进行强化,加入图片重复,图片超尺寸,字符串重复,对象重复分析与问题引用链聚类等更复杂的Hprof分析。

也许是基于Shark从代码层面的终极性能优化

- 分析源码问题

我们在分析Shark的源码的时候,发现了下面一些可以优化的问题,

  • 原生的堆对象代理体系索引较少,大部分操作使用Lazy Loading甚至为顺序查找,对一些要进行局部统计的操作极端不友好,耗时相对很长。
  • 不保证读取线程安全,多个分析无法在一个索引上同时进行。
  • 使用Okio + Position实现Lazy Loading,需要与IO进行交互,甚至在读取时都要创建一票对象,对GC造成压力,分析速度大大降低。
  • 对象代理体系封装死板,类型系统不够简洁,没有从外部穿透的灵活性,进行复杂业务分析困难,改写也较为困难。

根据这些问题,我们的优化目标聚焦下下面三点,

  • 大部分对象查找时间复杂度为O(1)
  • 建立索引后必须保证无锁的并发
  • 更简洁,高效,且优雅易用的代理对象体系

- 性能优化: Eager Loading

在具体实现思路上,我们在索引建立上使用了自己的一套体系,并且拥有全新的对象代理。

与shark不同,我们采用了较为激进的Eager Loading,对分析中常见的操作都建立了索引表,保证分析器查找取用数据的速度。这样一来也可以保证在索引建立完成后,所有的读取都是线程安全的,我们可以尽情的利用多核处理器的能力。

在另外一个层面上,根据业务的实际需求,我们针对代理对象的最短引用链获取做了特别的处理。即在分析时就将最短引用链求出,而不必像原有shark那样在用到时再进行计算。且在实际业务中要获取谁的引用链是无法预知的,这就造成了一个碰运气的问题:如果对象在BFS中遍历处于靠后的位置,或者是其根本从gc root不可达,再加之老方案遍历时是通过访问字段,而字段的加载又是极大可能要触发IO的。这样一整套组合拳下来,整个分析体验就会变得尤其糟糕。新Hprof通过牺牲一些内存,换取高速的引用链获取,极大地提高了体验。

优化前:

优化后:

- 性能优化:新索引系统

在初步的版本中,由于没有引用链分析的加入以及使用的hprof较为简单,除开启动预热时间,我们没有发现特别突出的性能问题。然而在加入了引用链分析后,甚至在简单hprof中多个分析器并行获取引用链也会消耗大量的时间与内存。

发现问题

在上一阶段中,我们发现由于引用链的并行获取,造成了时间的大量消耗与内存的飙高。问题在哪呢?

经过分析,我们得出一个结论,由于当时仍然是处于shark的体系之下,其线程不安全的读取让整个支持并行的策略看起来既滑稽又无奈:为多个分析器分配多个hprof对象,并且分别并行构建。这也直接导致了我们很难在进行分析前就将统一的最短引用链求出,当然其代码封装的高度不灵活性也是阻力的来源。

不仅如此,在原有体系下针对对象的全盘统计也是极为痛苦的,通过Profiling我们发现大多数时间都被耗费在了Okio与磁盘的读取交互上,让人无法接受。诸多不满之下,更换到一个新的索引系统的想法诞生了。

解决问题

在设计全新索引和代理体系时,我们尽可能将常用的查询通过映射缓存起来,例如类型名到代理类型对象等,此等操作在原有的索引下是实打实的O(n)时间消耗。这使得我们的任何统计操作时间被大大缩短。

并且针对到以后可能出现的复杂分析,我们特地为对象缓存了一个可达表与对应的可达性类型(实例字段,静态字段,JNI Local等)。

同时我们也借助上面的可达表进行对象最短引用链的构建,以一定的内存牺牲来使得引用链获取是无需任何时间的。

优化成果

功能强化,从内存分析小白到内存分析专家

在Android系统中,Java的语境下,那些内存分析小白就只是知道Activity内存泄漏,外网也有一堆这样的文章。Shark的核心分析能力,针对的也是Activity内存泄漏。好,我先来端正下概念。

Java没有真正意义上的“内存泄漏” = Memory Leaks 为什么这么说呢?

因为我们在C语言中的内存泄漏,更多是指无法释放的内存。而Java的“内存泄漏”都有明确的引用关系,怎么可能无法释放呢?如果没有了与GC Root的间接或者直接的引用关系,就会被GC回收。有点深,是不是没看懂。我们结合Activity内存泄漏来再次理解下。

每个还在内存中的Activity的实例,如果有引用关系就是泄漏,那么每个Activity都是泄漏,因为他都有被GC Root引用。这里肯定漏了些什么? 为什么leakcanary要监听Activity的生命周期呢?因为这个判断内存泄漏他们添加了一个前提,就是这个Activity的实例走到了Destory了,他应该被GC,但是并没有。

说到这里,我们不妨再抽象下。其实Java的内存问题的核心是,“应然”与“实然”之间矛盾,正如Activity被Destory,他应该被释放,但是实际他没有。来,我们可以放飞下自己的思维了

  1. 内容一样的内存实例,不应该重复出现,实际出现了
  2. 图片的内存占用应该依据屏幕尺寸,但实际超出了

落地到实处,我们在原有的泄露基础上,我们加入了四个对内存优化具有针对性的分析器:

  • 字符串重复
  • Bitmap重复
  • Bitmap超尺寸探测
  • 普通对象重复

除此之外,我们还强化了引用链的分析能力

除开泄露分析器,其他分析器也充分利用上了预加载的最短引用链信息,通过在一组内分析引用链的相似段,找出最普遍的引用链特征,精准定位群体事件的问题所在

让专家真正融入到QAPM中

在我们的日夜兼程的努力下,它完整地融合到了QAPM之中。提供更详细的信息:GC引用链,图片的预览,尺寸,像素通道,字符串的内容等等;并且配合提单系统的修复闭环。下面晒晒界面,也欢迎大家试用。

老页面

列表

详细信息

详细信息

新页面

基于精准的引用链聚合问题,让研发能借助大数据聚焦核心问题

详细的个例信息,助力问题分析

下半部GC引用链

图片预览:可放大查看,直观检查图片尺寸是否合适,是否可以使用RGB565

提单内容自动添加引用链等详细信息

总结,专家vs小白

新内存分析专家 vs. 小白(旧版与LeakCanary 2)

新内存分析

旧内存分析

LeakCanary 2

分析项

多样化,根据分析器制订

少量分析,根据规则制定

仅有泄露

分析结果

针对不同类型有专门化的详细信息(如图片的尺寸,像素信息等)

便利功能

拥有图片预览导出,字符串内容预览等便捷功能

少量

后续规划

虽然目前已经取得了一些成果,但这还远远不够。

  1. 我们需要更多的分析器加入,如对于普通集合类型的低效利用(过短或者持有过多的空引用),引用值类型的分析(java.lang.Integer)等。
  2. 导出更多分析信息(例如针对Bitmap在不同Android版本的信息获取),来更好的定位内存中的问题所在。
  3. 美化信息的输出,提供更加易读,准确的结果。
  4. 考虑提供演进更优的框架设计,获取更好的性能来提升我们的分析体验。
  5. 考虑使用更适合模拟大量小对象的语言进行重写

想了解更多QAPM详情,请咨询:QAPM

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 从0到1,QAPM在私有化实践过程中的质量保障

    QAPM(移动监控)在TMF中交付已经走过两个年头,两年的时间,我们也在不断成长。截止到2020年12月,QAPM私有化工单数量收敛,安灯工单数48单下降到8单...

    010101011001
  • QAPM — 一款强大且细腻的APP性能专项解决方案

    QAPM是我们腾讯云专项测试技术中心其中一个较为成熟的产品,是针对移动App的一个一站式性能解决方案。

    QAPM腾讯客户端性能分析
  • QAPM小程序性能监控难点与解决方案

    目前公司内外存在多个小程序的监控方案,包括微信提供的原生方案、Aegis、Fundebug和听云等,那么对比这些的监控方案,QAPM的小程序质量套件有什么不同呢...

    010101011001
  • “定位”那些事儿—sigkill定位爆内存问题

    导语:定位爆内存crash原因—iOS App性能中影响各位开发友人发量的重要问题,我们通过对QAPM上报的一例sigkill有效个例的分析,为大家提供一些思路...

    QAPM腾讯客户端性能分析
  • 精选腾讯技术干货200+篇,云加社区全年沙龙PPT免费下载!

    “看一看”推荐模型揭秘!微信团队提出实时Look-alike算法,解决推荐系统多样性问题;

    风间琉璃
  • QAPM新版本:AI聚合,效率提升305%(Android2.5.2)

    QAPM是一款全方位定位检测 APP 应用性能的 SDK,简单易用、并能提供多维度检测及分析,只需简单的调用几个接口,就能对 APP 做全方位的性能检测。

    QAPM腾讯客户端性能分析
  • 【私有化质量实践2】最“年轻”的云原生数据服务

    随着云架构的不断普及,“未来的软件一定生长于云上”的理念被越来越多的人所接受。云提供了一种面向企业应用实现按需进行资源分配的模型,以一种全新的、高效的方式来部署...

    010101011001
  • android开发书籍推荐大全

    android开发书籍推荐大全 ? 写在前面 首先,不提供电子版本的下载,请大家自行百度,如果还是找不到,可以加微信联系我。 再次很感谢写...

    用户1263308
  • 互联网寒冬下那些 Android 开发高手,都在研究什么技术?

    近半年来,很多人都问过我这样的问题。大家对于职业的未来,都有一些迷茫和焦虑,其实我也有,为什么会这样呢?

    Android技术干货分享
  • 能“理解代码”的缺陷分配服务之技术内核

    如果缺陷没有分配给正确的人,会导致重要缺陷不断流转,很慢才能解决;而在流转的过程中会增加大量的交接成本——我们观察到一个简单的缺陷在流转中会浪费超过5天(见下图...

    010101011001
  • 告别重复告警打扰--基于堆栈相似度的全新QAPM告警方案

    导语 为了能够及时的发现问题并及时解决,QAPM提供了一套卡顿告警机制。正如同常规的阈值触发的告警机制一样,QAPM早期的告警也会使测试开发人员陷入告警风暴的影...

    QAPM腾讯客户端性能分析
  • awesome-programming-books

    100+ 经典技术书籍,涵盖:计算机系统与网络、系统架构、算法与数据结构、前端开发、后端开发、移动开发、测试、项目与团队、程序员职业修炼、求职面试 和 编程相关...

    guanguans
  • 亮相深圳2019MTSC大会,腾讯WeTest携手行业专家搭建“质量专场”

    ? 背景   12月14日,2019年度中国移动互联网测试开发大会(Mobile Testing Summit China,简称 MTSC)深圳站于深圳科兴...

    WeTest质量开放平台团队
  • 年薪80万的区块链技术开发,今日带你免费入门

    被称作下一代互联网技术的区块链,最近半年时间可谓火遍全球,从币圈、链圈到矿机圈,各种暴富神话都在不停上演,这一轮暴富效应让许多圈外人士羡慕不已,也让区块链技术的...

    用户1564362
  • 读书单

    Java高级架构
  • React#31 error,让我熬夜让我秃

    卡颂日常从事基础架构相关工作。这次接到一个任务:封装一个React组件交给业务方使用。

    公众号@魔术师卡颂
  • 校招进大厂,分享 Tom哥的读书单

    大家好,我是Tom哥。校招进阿里,研究生,P7技术专家,出过专利,竞赛拿过奖,CSDN博客专家,负责过电商交易、社区生鲜、营销、金融等业务,多年团队管理经验,爱...

    用户7676729
  • 邀您参加 | BigData & Alluxio 交流会-成都站

    本期技术沙龙将会聚焦在大数据、存储、数据库以及Alluxio应用实践等领域,邀请腾讯技术专家和业界技术专家现场分享关于Alluxio系统的基本原理、大数据系统架...

    云加社区技术沙龙
  • 帝国的灵魂:谷歌大脑

    大数据文摘

扫码关注云+社区

领取腾讯云代金券