1、问题描述
长时间monkey测试发生android重启。
2、问题分析过程
【初步分析】
首先确定system_server重启原因,从android log看,系统没有发生native/java crash、anr、surfaceflinger等重要服务发生重启等异常,从kernel log看,发现system_server有被kill。原因是out of memory。Log如下:
418[01-01 21:46:38.283] <3>[49366.984650] c4 5184 Out of memory: Kill process 4288 (system_server) score 0 or sacrifice child
419[01-01 21:46:38.283] <3>[49366.985612] c4 5184 Killed process 4288 (system_server) total-vm:4572168kB, anon-rss:0kB, file-rss:0kB
上面log可以确认两件事情,一是system_server是被kernel的oom kill的,说明系统内存不足很严重,有较为严重的内存泄露,kernel无法回收到更多内存用于正常流程执行,开始杀用户态占用内存较多进程。二是这里杀system_server并不能说明一定是system_server有内存泄露,只能怀疑是存在泄露。因为kernel oom kill机制中计算用户态被杀进程是通过oom_badness函数中对进程进行打分来确定要杀谁,而这里优先杀用户态进程,所以如果内核进程发生内存泄露,导致内存大量消耗也会优先查杀用户态进程。通过kernel log和meminfo,slab info等信息,我们初步判断不是kernel有内存泄露,这里system_server有内存泄露,是java heap有泄露还是native heap泄露,就需要继续分析。通过脚本进行测试,抓取showmap信息分析。log如下
virtual shared shared private private
size RSS PSS clean dirty clean dirty swap swapPSS # object
36864 21016 19097 0 1980 0 19036 0 0 10 [anon:libc_malloc]
126976 17996 17451 80 504 236 17176 13892 12632 19 [anon:libc_malloc]
151552 30800 30239 88 504 384 29824 18696 17433 20 [anon:libc_malloc]
159744 18908 18384 264 296 652 17696 17608 16325 20 [anon:libc_malloc]
159744 20560 20045 500 56 192 29812 25148 23853 20 [anon:libc_malloc]
159744 26996 26507 492 44 684 25776 29344 28053 20 [anon:libc_malloc]
159744 10940 10458 532 16 328 10064 47444 46171 20 [anon:libc_malloc]
167936 18946 28507 52 4 12 3680 61112 59448 20 [anon:libc_malloc]
从上面信息可以看出在8个小时的过程中system_server的内存占用持续上升,说明是native heap泄露,接下来需要查找泄露点。
方法是使用系统自带的malloc_debug来查找,当然分析native 层内存泄露还有其他工具可以使用。
【开malloc_debug】
$adb root
$adb remount
$adb shell
<