KOOM简介与接入
KOOM(Kwai OOM, Kill OOM)是快手性能优化团队在处理移动端OOM问题的过程中沉淀出的一套完整解决方案。
高性能线上内存监控方案,https://github.com/KwaiAppTeam/KOOM
依赖配置
l 项目根目录 build.gradle 中增加 mavenCentral
repositories { mavenCentral() }
l 项目 app/build.gradle 中增加依赖
dependencies { implementation “com.kuaishou.koom:koom-java-leak:2.2.0”
}
KOOM初始化
注意事项
1、一定需要在自定义的Application中初始化MonitorManager;
KOOM会开启IntentService启动hprof(内存快照)解析,该Service注册于子进程: heap_analysis!
2、MonitorManager初始化为非DebugMode,则一个APP版本:
2.1、第一次触发OOM完成dump与分析内存后,超过15天再次触发OOM,不再dump与分析内存快照;
2.2、触发四次OOM完成dump与分析内存后,第五次不再dump与分析内存快照; 15天与5次可在初始化MonitorManager时配置 3、KOOM不是内存泄漏时触发内存的dump与分析,而是周期性检测,在满足以下情况触发:
3.1、APP内存占用率超过内存阈值(默认:),且连续三次检测中,后一次检测没有比前一次降低0.05;
3.2、线程数量超过阈值,且连续三次检测中,后一次检测没有比前一次检测减少50个线程;
3.3、文件描述符超过阈值,且连续三次检测中,后一次检测没有比前一次检测减少50个文件打开数;
3.4、APP内存占用率超过阈值;
3.5、当前内存占用率-上次检测内存占用率大于阈值(内存占用率增长过快)
线上APM
为什么LeakCanary不能用于线上?
1、LeakCanary通过弱引用关联对象连续两次主动触发GC判定是否泄露,频繁GC易导
致程序卡顿;
2、每次检测到泄露都会dump快照文件,同一个泄露多次触发也会dump多份快照;
3、dump hprof文件(内存镜像)耗时,易造成程序长时间无响应;
4、hprof文件太大,解析耗时
周期轮询检测
内存检测
线程与文件描述符检测
Dump hprof
fork子进程
fork与多线程
在多线程执行的情况下调用fork()函数,仅会将发起调用的线程复制到子进程中,其他线程均在子进程中立即
停止并消失。但父进程全局变量的状态以及所有的pthreads对象(如互斥量、条件变量等)都会在子进程中得以保留!
因此,当子进程中进行dump hprof时,SuspendAll触发暂停是永远等不到其他线程返回结果,从而导致子进程阻塞卡死!
KOOM内存dump
先在主进程执行SuspendAll,使ThreadList中保存的所有线程状态为suspend,之后fork,此时子进程执行dump hprof,由于其共享父进程的ThreadList全局变量,因此认为全部线程已经处于suspend状态,避免了子进程dump时SuspendAll触发暂停等不到线程返回结果的情况。fork完毕父进程即可立刻执行ResumeAll恢复运行