线上场景

前面几节我们主要介绍了线下场景的监控,线下场景不管是 android studio 还是 MAT 或者 adb命令都可以直接使用,但线上场景就不行了,一是不能直接连接,二是设备数量众多,不可能每台都看,所以我们采用两步走的”远程坐诊”方式来解决这个问题。(因为UI和CPU基本在线下场景就能解决,故本节我们主要针对内存监控进行介绍)。

可分为两步
第一步,通过代码将设备的基本信息记录到日志中,如果低于预期可以报警
第二步,针对报警的设备dump出详细内存信息供下载查看

第一步
内存:

ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);  am.getMemoryInfo(memInfo ); 
long deviceMemory = memInfo .totalMem;  
long freeMemory = memInfo .availMem; 
long threshold = memInfo .threshold; 
long lowMemory = memInfo .lowMemory;

或者:

最大内存: Runtime.getRuntime().maxMemory(); 
当前使用内存: Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();

CPU不能直接通过API获取,是通过读取系统内的文件信息获得,代码就不贴出来了,大家可以参考:
https://www.jianshu.com/p/6bf564f7cdf0

其它信息包括网络,电量根据实际情况也可以记录一下。

第二步:
如果第一步收集的信息(主要是内存)低于阈值(自己设定),那么就dump出内存快照,一行代码即可:
Debug.dumpHprofData(filePath)
(其具体实现在源码 art/runtime/hprof/hprof.cc 中);

先将快照输出至指定目录,然后再上传至服务器即可(自己实现),接着再将此文件下载到本地,有了这个文件,后面的操作就和 线下场景的内存一模一样了,通过hprof-conv.exe命令转换后,导入到工具里查看即可,就像是你把自己的血液样本(其它样本也可)寄给了千里之外的医生,即使不在你的身旁,也能用仪器检测出病因。

直接使用dumpHprofData这个方法会引起进程冻结,应用会卡顿几秒,体验很不好,快手的团队针对这种情况,给出了优化的解决方案:fork出一个一模一样的进程(叉子进程),在新进程进行dump,从而不影响正在使用的进程。这个就涉及到native层的操作了,大家可参考快手的解决OOM的开源库:KOOM 。
https://baijiahao.baidu.com/s?id=1674693121890730020&wfr=spider&for=pc

除了用代码生成内存快照外,使用adb命令也可以,并且这种方式可以直接导入到as中无需进行格式转换(MAT还是要转换的)。但是因为众多的手机厂商对系统都进行了定制化的修改,所以这种方式兼容性并不好,在一些机型上可能失效。
adb shell am dumpheap pid /data/local/tmp/x.hprof (pid替换成你应用的进程id)

最后,还有一点要注意,因为dump函数比较耗时,在发生OOM之后再去执行dump操作,可能捕获不到有效信息,最好是在OOM发生前进行dump,用第一步的方式定时去查询内存,如果超过阈值,那么就dump,不要等到异常发生了才去dump。

Tips:
1.Dump后的.hprof往往很大,我实测会有4,50M左右(仅供参考),这对流量,存储都提出了很高的要求,这又引申出了一个概念:裁剪 hprof 文件,它的目的是去除一些无关紧要的信息,让其体积减少,便于网络传输和存储。Hprof文件也是遵循一定的协议或者说格式(如下图),基于这个对其修改,达到裁切的目的。

图片1.png

可以参考西瓜视频的内存快照裁剪压缩工具 Tailor
https://blog.csdn.net/ByteDanceTech/article/details/111189304
或者美团的Probe
https://tech.meituan.com/2019/11/14/crash-oom-probe-practice.html

2.我们熟知的LeakCanary核心也用到了dumpHprofData来生成内存快照,位于独立的HeapAnalyzerService进程,而解析是由开源项目HAHA(https://github.com/square/haha)来完成。

dumpHprofData方法这个只是获取Java堆的信息,应用中还包含了 Native内存的信息,这部分内存是由业务动态申请的内存,一般是业务so库,业务代码是c/c++实现的,常用的方式就是调用 malloc函数申请内存,调用free释放内存。这些内存的申请都需要合理的释放,否则会导致内存不足。可结合Debug.getMemoryInfo()以及/proc/pid/smap文件来分析。
关于线上native内存的泄漏监控,我们可以参考西瓜视频Raphael: https://github.com/bytedance/memory-leak-detector

最后,我们来整体看下线上场景APP监控的流程(引用了腾讯全民K歌的整体分析流程):

图片2.png

基本流程是通过监控系统得出记录文件 再交给本地分析和后台分析,做的好的,可以将分析结果与项目管理软件相关联,直接将BUG指派到人。

总的来说,我们不是只懂得一些内存泄露解决方法就可以,更重要的是通过日常测试与监控,得到内存泄露检测与修改的一整套闭环体系。有了这一套体系或者流程,开发测试的效率提高,应用的质量得到极大的保证。当然,对于很多中小公司来说,这么做可能有点本末倒置了,实际中需要去衡量投入与产出比及带来的价值。

图片3.png

总结:
1.线上的监控相比线下更有难度,只有个别实力雄厚的大厂才能建立一套完整的闭环体系。我们要结合自身的情况去做监控方案,否则就得不偿失了。
2.监控功能的开关和灰度很重要,最好能做到可控,一旦监控本身有问题,可以及时关闭。
微信甚至上过一种兜底方案:在内存逼近临界值时,把自己kill掉。。。也就是说把本来的系统行为提前转为自己的应用行为了,充分体现了控制反转的思想。但这种做法风险系数很高,只能针对一小部分用户灰度。
3.线上和线下结合才能包治百病。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容

  • 体现App稳定性的一个重要数据就是Crash率,而在众多Crash中最棘手最难定位的就是OOM问题。本文主要分享美...
    Kepler_II阅读 786评论 0 1
  • https://zhuanlan.zhihu.com/p/133816365 四、内存抖动 当内存频繁分配和回收导...
    kkgo阅读 464评论 0 0
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,520评论 28 53
  • 信任包括信任自己和信任他人 很多时候,很多事情,失败、遗憾、错过,源于不自信,不信任他人 觉得自己做不成,别人做不...
    吴氵晃阅读 6,181评论 4 8
  • 怎么对待生活,它也会怎么对你 人都是哭着来到这个美丽的人间。每个人从来到尘寰到升入天堂,整个生命的历程都是一本书,...
    静静在等你阅读 4,956评论 1 6