文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

MemoryThrashing:抖音直播解决内存抖动实践

2024-12-01 18:53

关注

背景介绍

直播 OOM 问题比较棘手难以定位,主要体现在涉及的业务很多,从定位到解决花费时间比较久。为了提前触达问题,提高定位的效率,也是对现有工具的补充,提出直播内存抖动解决方案- MemoryThrashing。

为什么要提出这个方案 ?

什么是 Thrashing(抖动) ?

维基百科中 thrashing 定义: 

从业务视角定义内存 thrashing:

通俗讲就是性能数据有大的波动,拿内存来讲,当内存短时间从 600M 涨到 800M 叫作一个抖动。希望通过自研工具找出这 200 M 内存增长来自于哪里,在实际的 OOM 案例中因内存突增导致的 OOM 是比较常见的,具体现象如下:

以临时对象、内存堆积为例来阐述如何定位该类问题,通过“AllocTime Summary” 描述临时对象分配次数,通过 “Memory Summary” 描述内存堆积。

临时对象

临时对象:短时间分配大量对象,导致直播稳定性波动较大,可能使内存、CPU 负载变高。这类问题通常表现为短时间内存冲高或者直接 OOM,或之后开始迅速回落到正常水位,这类对象不会驻留内存过久,通过监控 “临时对象” 可以提前发现这类问题。

以上是按分配次数(AllocTime Summary)统计的 TOP 临时对象,“AllocTime Summary 1” 代表第一次采样 Class 的分配次数其它依次类推。举例:通过 diff “AllocTime Summary 2” 与 “AllocTime Summary 1” 差值可知 “LivexxxA” 在采样周期分配了 7803 次,由于未采集到 “Memory Summary” 信息,可认为未有内存驻留。

内存堆积

内存堆积:内存驻留了大量对象,而且这类对象短时间不会释放掉,导致内存水位居高不下,很容易触发 OOM 问题。

以上是按内存驻留统计的 TOP 实例,“Memory Summary 1” 代表第一次采样实例数量的内存驻留信息其他依次类推。举例:通过 diff “Memory Summary 2” 与 “Memory Summary 1” 可知 “LivexxxA” 在采样周期内增长了 56791 个,根据最后一次采样可知内存驻留了总共 69904 个实例,通过采样可知“LivexxxA” 每次都是递增的。

MemoryThrashing 方案

方案调研

方案思路是做内存差值找出增长,通过采样多个时刻的内存信息(目前主要监控 Class 的实例个数), Diff 出内存信息找出 TOP 增长,达到归因的目的。

内存区

通过内存节点遍历与已注册的 Class 比较统计实例个数,该方案的优点是可以监控整个 APP 的 OC 对象实例个数,面对直播业务场景需不需监控整个 APP 的对象,目前看暂时用不到,需求出发点是监控直播场景且满足一定条件。比如:直播观播一段时间后内存的大幅波动,场景比较聚焦。另一个考虑是如果当前内存比较大,遍历 zone 会比较耗时,如果不挂起线程会有潜在的崩溃问题、以及数据不准问题。

RunTime

通过 Hook 的方式,统计 Class 实例的分配、释放次数,达到记录实例存活个数的目的,可监控固定场景的 OC 实例增长情况,如直播间内的内存突增,范围比较小不需要统计过多的无用对象。该方案相对内存区遍历耗时小,且不会有野指针问题。但需要注意的是监控对象时对性能的影响,目前采用的是 RunTime 方案,从线下直播间测试情况看对主线程的影响忽略不计。

方案设计

在实际开发过程中发现对象的创建、释放处于复杂的多线程环境中,处理不当会对业务产生潜在的影响,影响到业务执行效率或者造成稳定性问题:

经过优化采用多级缓存方案解决主线程的性能开销问题,达到主线程几乎零开销。

监控流程

在进入直播间一段时间后开启监控,通过监控内存值变化来区分是否开启采样功能,开启采样后会进入连续多次采样阶段,多次采样完成后进行数据上报,上报完成后会继续监控内存。

数据展示

在高热直播间多次采样的内存快照,采集 TOP 100 数据,以 “LivexxxA” 为例两次采样中第二次增长了 4125 个实例,可以简单归因 “LivexxxA” 相关业务导致 “MemoryThrashing”,可以从 “LivexxxA” 相关业务入手排查。

方案优缺点

方案

优点

缺点

“MemoryThrashing”

可以多次采样,对比内存增长趋势;性能开销小,可线上全量;提前感知内存问题;上手简单,通过对象数量就可以排查问题;

不支持多语言,只限于 oc 语言;不具备通过内存节点关系分析内存泄漏问题,只能找出堆积的对象;不具备分析多个内存区的能力;Hook 方式影响方法缓存;

“MemoryGraph”

问题发现能力强:可以通过内存节点关系分析内存泄漏导致的 OOM 问题;可以统计内存区的内存占用情况;适用多语言;上手复杂,需要梳理内存节点引用关系;

线程挂起会影响业务执行,用户感知明显;内存使用越高,内存区遍历越耗时;只能少量采样;

实践案例

目前 “MemoryThrashing” 已经部署了,可以监控测试环境,后续将部署到线上。通过线下看提前暴露了很多问题,相对以往方式只有问题发生了或者产生了明显影响才能感知到,需要 QA 反馈到 RD,通过“MemoryThrashing”大大提升了排查效率,很好的将劣化问题前置发现,以下抽取其中两个案例。

内存堆积

如下,多个采样周期内出现了大量对象的分配问题,且这些对象未释放,并且导致了内存明显上涨,采样周期 3 比采样周期 2 多分配了 234024 个对象,且最后内存驻留了 238800 个 “LivexxxBigDataRead” 对象,占用内存 10.9M。

临时对象

如下,是开播场景抓到的问题,在主播端开启弹幕狂欢时,过 Effect 认出人脸后,就会创建一个对应的轮廓模型给到中台去画轮廓,频率会很高,每 5 秒周期(实际时间更小)临时对象增量高峰可到 6w 个(后两次采样差值),由于未生成 “Memory Summary” 信息可认为未驻留内存 ,累计过百万次对象分配,对开播性能会产生直接影响:

未来规划

归因能力

只统计 OC 对象数据在某些情况下可能不够,比如公共基础对象异常增长,则没有办法追踪到具体成因,如果带有对象引用关系可以进一步锁定问题。当然这些都是对 “Memory Graph” 能力的补充,如果“Memory Graph” 已经抓到了数据,可以结合“Memory Graph” 锁定对象引用链路继而找到业务。

CPU 监控

根据以往案例如:OOM、ANR 有不少会伴随着高 CPU 使用率,比如某次案例由大量数据处理导致的 OOM 问题,经排查发现负责该业务处理的线程 CPU 使用率很高,所以通过监控线程 CPU 使用率,来补充监控显得很有必要,可以通过线程名字、堆栈, 锁定怀疑的业务。

来源:字节跳动技术团队内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯