GMTC 全球大前端技术大会 8 折涨价倒计时 2 天,现在购票立减 ¥960 ! 了解详情
写点什么

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

2020 年 8 月 12 日

快手开源自研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 年 8 月 12 日 15:262280

评论

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

一个草根的日常杂碎(10月19日)

刘新吾

随笔杂谈 生活记录 社会百态

一个草根的日常杂碎(10月20日)

刘新吾

随笔杂谈 生活记录 社会百态

深入java week1-01 字节码、内存、GC、调试工具

闷骚程序员

甲方日常 35

句子

工作 随笔杂谈 日常

机器学习是什么?

马同学

学习

吃透阿里大佬整理的Java面试要点手册,成功五面进阿里(二本学历)

Java架构追梦

Java 学习 架构 面试 核心知识点整理

利用区块链等技术,加强对交通运输信用信息的归集共享和分析应用

CECBC区块链专委会

区块链 交通运输

央行数字货币离我们还有多远?

CECBC区块链专委会

数字货币

AI让远程交流“更清晰”:GAN消除视频通话中的抖动

Geek_459987

LeetCode题解:98. 验证二叉搜索树,递归中序遍历过程中判断,JavaScript,详细注释

Lee Chen

算法 LeetCode 前端进阶训练营

架构师必备的那些分布式事务解决方案!!

架构师修行之路

分布式 微服务 架构设计

【线上排查实战】AOP切面执行顺序你真的了解吗

Zhendong

spring aop

二十、深入Python迭代器和生成器

刘润森

Python

年纪轻轻怎么就卵巢早衰了?试管可帮忙!

Geek_65d32f

试管 三代试管

数据结构与算法系列之链表操作全集(一)(GO)

书旅

go 数据结构 数据结构和算法

分布式下,我想要一致性

架构师修行之路

分布式 微服务

java week1练习

闷骚程序员

Flink窗口算子-6-8

小知识点

scala 大数据 flink

Go语言内存管理三部曲(三)图解GC算法和垃圾回收原理

网管

go 内存管理 垃圾回收 GC GC算法

架构师训练营 1 期 -- 第五周作业

曾彪彪

极客大学架构师训练营

typora增强-mac

老菜鸟

Typora

架构必修:领域边界划分方法--职责驱动设计(RDD)

马迪奥

架构 领域 架构师 RDD

vivo 商城前端架构升级—前后端分离篇

vivo互联网技术

Java 前端 前后端分离

解析 CloudQuery 审计分析功能

CloudQuery社区

数据库 sql 安全 工具软件

学了那么多 NoSQL 数据库 NoSQL 究竟是啥

哈喽沃德先生

数据库 nosql 非关系型数据库

iOS性能优化 — 一、crash监控及防崩溃处理

iOSer

性能优化 ios开发 Crash 监控及防崩溃处理

Linux的上手命令

林昱榕

Linux 常用命令

mPaaS x Menxlab | 1024程序员节:Talk is cheap,Show me the AppID

蚂蚁集团移动开发平台 mPaaS

程序员 开发者 mPaaS 1024

攻克金融系统开发难点,借助SpreadJS实现在线导入Excel自定义报表

Geek_Willie

SpreadJS 在线导入excel

Microsoft Azure机器学习采用NVIDIA AI为Word编辑器提供语法建议

Geek_459987

千万不要往 Shell 里粘贴命令!

大道至简

命令行

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