速来报名!AICon北京站鸿蒙专场~ 了解详情
写点什么

快手开源自研 OOM 解决方案 KOOM

  • 2020-08-12
  • 本文字数:1700 字

    阅读完需:约 6 分钟

快手开源自研OOM解决方案KOOM

近日,快手宣布开源自研 OOM 解决方案KOOM。据了解,KOOM 是在客户端完成内存监控后,将解析报告上传到云端,传输文件大小仅为 KB 级,运行时用户无感知,对流量基本无影响,适合大规模普及应用,目前该方案已在快手全量业务中应用,OOM 率降低了 80%以上,效果显著。


OOM 是当前 Android 开发中的常见疑难问题,尤其是线上发生的 OOM 问题极难定位。业界当前最知名的方案 LeakCanary,通过监控 Activity/Fragment 泄漏优化 Java OOM 问题,多年来一直为广大 App 保驾护航,解决了 OOM 治理从 0 到 1 的问题。但面对行业不断复杂的业务环境和庞大用户流量,LeakCanary 仍有优化空间:受限于性能,无法在线上大规模部署,仅支持线下使用;只能定位 Activity&Fragment 泄漏,无法定位大对象、频繁分配等问题;需要人工一一分析,无法对问题聚类量化……为了彻底解决 OOM 问题,行业尝试了多种解决方案,通常是基于 LeakCanary 做优化,但至今没有能完全解决监控过程中的性能问题,普遍解决方法是通过采样的办法牺牲一小部分用户的体验来定位问题。


快手 OOM  Killer 沿用行业的研究思路,针对 LeakCanary 无法解决的难题进行自研改造,充分发挥 LeakCanary 原有优势的同时补足短板,打造了一套可以线上部署、兼顾线下、配置灵活、适用范围广泛、高度自动化,埋点、监控、解析、上报、分发、跟进、报警一站式服务的闭环监控系统,将绝大多数 OOM 问题拦截在灰度阶段,彻底解决了 OOM 问题。



KOOM 框架


快手 KOOM 核心流程包括:配置下发决策、监控内存状态、采集内存镜像、解析镜像文件(以下简称 hprof)生成报告并上传、问题聚合报警与分配跟进。

无主动触发 GC 不卡顿

之前行业的普遍做法是通过在 Activity.onDestroy()后连续触发两次 GC,并检查引用队列,判定 Activity 是否发生了泄漏,但频繁 GC 会造成用户可感知的卡顿,快手为实现无感触发设计了全新的监控模块,通过无性能损耗的内存阈值监控来触发镜像采集。将对象是否泄漏的判断延迟到了解析时,阈值监控只要在子线程定期获取关注的几个内存指标即可,性能损耗忽略不计。



内存监控流程图

高性能镜像 DUMP

采集内存镜像传统方案会造成应用完全冻结长达几秒,期间用户完全不能操作,严重损害用户体验。快手利用系统内核 COW(Copy-on-write,写时复制)机制,每次 dump 内存镜像前先暂停虚拟机,然后 fork 子进程来执行 dump 操作,父进程在 fork 成功后立刻恢复虚拟机运行,整个过程对于父进程来讲总耗时只有几毫秒,对用户完全没有影响。


暂停虚拟机需要调用虚拟机的 art::Dbg::SuspendVM 函数,谷歌从 Android 7.0 开始对调用系统库做了限制,快手自研了 kwai-linker 组件,通过 caller address 替换和 dl_iterate_phdr 解析绕过了这一限制。



Fork dump hprof 流程图

“不偷”用户流量的解决方案

传统方案得到的 hprof 文件通常比较大,占用用户大量磁盘空间,上传大文件浪费用户流量,且不利于问题聚类分析。快手采用了新的思路:采用边缘计算的思路,将内存镜像于闲时进行独立进程单线程本地分析,不过多占用系统运行时资源;分析完即删除,不占用磁盘空间;分析报告大小只有 KB 级别,不浪费用户流量。


分析报告生成流程总体分为三个环节,第一个环节扫描镜像构建索引,建立泄露查找分析的基础;第二个环节查找出泄露的对象,根据既有的 framework 知识以及人为设定的策略,执行对象泄露判定;第三个环节生成最终报告文件,将对象泄露路径、泄露数量、类统计、运行时信息添加至报告文件,辅助后续根据报告分析解决 OOM 问题。



解析镜像生成报告流程图


针对镜像回捞需求,对 hprof 进行运行时 hook 裁剪,只保留分析 OOM 必须的数据。裁剪还有数据脱敏的好处,只保留对分析问题有用的内存中类与对象的组织结构,并不上传真实的业务数据,充分保护用户隐私。

总结展望

快手 KOOM 计划做完整的客户端内存解决方案,开发者可以通过接入 KOOM,解决自己项目中的 OOM 问题。此次一期开源暂时只包括 Android Java OOM 解决方案,后续还将开源 Android 线程/文件描述符监控、Android Native OOM 监控、iOS OOM 监控等,最终实现帮助开发者解决各种场景下 OOM 的愿景。

项目地址:

https://github.com/KwaiAppTeam/KOOM


2020-08-12 15:264618

评论

发布
暂无评论
发现更多内容

对接量化钱包区块链开发

v16629866266

程序员防猝死指南

小白debug

程序员 职业 内存 打工人 Go 语言

嘿,同学,你要的Java内存模型(JMM)来了

Simon郎

Java 大数据 JVM

第4周左右

林亚超

记录一次BAT一线互联网公司前端JavaScript面试

我是哪吒

JavaScript 学习 面试 大前端 2月春节不断更

华云大咖说 | 大型分布式监控系统建设经验

华云数据

即拼商城模式开发

luluhulian

MyChat,一个私有的“微信“

米凤君

Java 微信 Netty IM JavaFx

我用 Python 分析了一波热卖年货,原来大家都在买这些东西?

JackTian

Python 数据分析 数据可视化 2月春节不断更 年货

ARTS打卡 第30周

引花眠

微服务 ARTS 打卡计划

Redis Sentinel 源码:Redis的高可用模型分析

华为云开发者联盟

数据库 redis 高可用 框架 redis sentinel

华为 Python网络自动化

艺博东

Python 网络

3. 无转折不编程,滚雪球学 Python

梦想橡皮擦

Python python从入门到精通 2月春节不断更 python入门

笔记本电脑电池显示4%可用(已接通电源),经过清灰又莫名奇妙的可以续航啦,很奇怪!

孙叫兽

电脑故障 电池

京东App Swift 混编及组件化落地

京东科技开发者

swift 开发者

使用Travis CI为工程搭建一个持续集成服务。

梁龙先森

大前端 持续集成 2月春节不断更

同时拿到BATJMD的Offer是怎样的一种体验?

冰河

面试 面经 offer 一起进大厂 BATJMD

如何极速极速搭建个人博客?Copy攻城狮用的这一招很优秀!

华为云开发者联盟

JavaScript typescript GitHub React #Serverless

从架构设计理念到集群部署,全面认识KubeEdge

华为云开发者联盟

架构 容器 云原生 集群 kubeedge

图文详解:如何给女朋友解释什么是微服务?

浅羽技术

Java zookeeper 分布式 微服务 框架

编程范式( Programming paradigm )简介

引花眠

编程范式

大作业一:

未来已来

数字化人才有哪些特性?

boshi

数字化转型 七日更

第十一周 安全稳定知识课后作业

简简单单

Python进阶丨如何创建你的第一个Python元类?

华为云开发者联盟

Python 编程 python元类 对象 装饰器

第6周作业

Geek_mewu4t

一看就懂的var、let、const三者区别

蛙人

JavaScript

研发效能,productivity 还是 performance

李小腾

第十一周 学习总结

简简单单

ZEGO即构自建MSDN有序网络,为实时音视频传输极致顺畅!

ZEGO即构

大学寒假这样过,过完惊艳所有人,不只是你的宿友,还有千千万万个程序员同行们!!!

沉默王二

程序员

快手开源自研OOM解决方案KOOM_架构_快手技术_InfoQ精选文章