Lowmemkill问题分析
前言
由于我们POS采用的是1+8的硬件设计结构,所以经常会出现由于内存占用过高而导致一些应用被杀死,由于这些机器在商户手里,且杀死的应用虽然对于android来说认为并不重要,但是对应用调用的关系非常重要。这篇文章就是在这个前提的基础上开展的,主要通过工具和查看日志的方法定位内存使用情况和应用被杀死的情况。
一.概述
Android底层还是基于Linux,在Linux中低内存是会有oom killer去杀掉一些进程去释放内存,而Android中的lowmemorykiller就是在此基础上做了一些调整来的。因为手机上的内存毕竟比较有限,而Android中APP在不使用之后并不是马上被杀掉,虽然上层ActivityManagerService中也有很多关于进程的调度以及杀进程的手段,但是毕竟还需要考虑手机剩余内存的实际情况,lowmemorykiller的作用就是当内存比较紧张的时候去及时杀掉一些ActivityManagerService还没来得及杀掉但是对用户来说不那么重要的进程,回收一些内存,保证手机的正常运行。
lowmemkiller中会涉及到几个重要的概念:
/sys/module/lowmemorykiller/parameters/minfree:里面是以”,”分割的一组数,每个数字代表一个内存级别
/sys/module/lowmemorykiller/parameters/adj:对应上面的一组数,每个数组代表一个进程优先级级别
举个例子:
/sys/module/lowmemorykiller/parameters/minfree:18432,23040,27648,32256,55296,80640
/sys/module/lowmemorykiller/parameters/adj:0,100,200,300,900,906
代表的意思:两组数一一对应,当手机内存低于80640时,就去杀掉优先级906以及以上级别的进程,当内存低于55296时,就去杀掉优先级900以及以上的进程。
对每个进程来说:
/proc/pid/oom_adj:代表当前进程的优先级,这个优先级是kernel中的优先级,这个优先级与上层的优先级之间有一个换算,文章最后会提一下。
/proc/pid/oom_score_adj:上层优先级,跟ProcessList中的优先级对应,上述的相关值在不同的机型上有不同,这个决定于硬件的配置和各个厂家工程师的调教。
二.Lowmemorykiller 的日志查询
系统卡顿进行adj相关优化的时候往往会触发lowmemorykiller,查看应用是否被lowmemorykiller的日志,可以从如下的几个维度进行:
2.1 logcat抓取的日志
2.2 logcat -b events抓取的日志
2.3 kernel的日志
如果有上述的日志,那么恭喜你你的应用是由于低内存被杀了。
三.分析内存利器工具
如果想查看所有进程的内存使用情况,可以使用命令procrank、dumpsys meminfo查看,当然也只可以过滤出某个进程如:dumpsys meminfo | grep -i phone
3.1 先来看procrank,有些android平台和终端可以不带这个命令,这个就需要下载可以使用的busybox带这个的使用
从以上打印可以看出,一般来说内存占用大小有如下规律:VSS >= RSS >= PSS >= USS
VSS - Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)是单个进程全部可访问的地址空间
RSS - Resident Set Size 实际使用物理内存(包含共享库占用的内存)是单个进程实际占用的内存大小,对于单个共享库, 尽管无论多少个进程使用,实际该共享库只会被装入内存一次。
PSS - Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)
USS - Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存)USS 是一个非常非常有用的数字, 因为它揭示了运行一个特定进程的真实的内存增量大小。如果进程被终止, USS 就是实际被返还给系统的内存大小。
USS 是针对某个进程开始有可疑内存泄露的情况,进行检测的最佳数字。怀疑某个程序有内存泄露可以查看这个值是否一直有增加
3.2 使用dumpsys meminfo查看内存信息
3.3 adb shell top命令
top命令提供了实时的对系统处理器的状态监视.它将显示系统中CPU最“敏感”的任务列表.该命令可以按CPU使用.内存使用和执行时间对任务进行排序.
adb shell top:
各组数据的含义如下:
第一组数据的含义:
User 处于用户态的运行时间,不包含优先值为负进程 Nice 优先值为负的进程所占用的CPU时间 Sys 处于核心态的运行时间 Idle 除IO等待时间以外的其它等待时间 IOW IO等待时间 IRQ 硬中断时间 SIRQ 软中断时间
第二组数据的含义:
PID 进程id PR 优先级 CPU% 当前瞬时CPU占用率 S 进程状态:D=不可中断的睡眠状态, R=运行, S=睡眠, T=跟踪/停止, Z=僵尸进程 #THR 程序当前所用的线程数 VSS Virtual Set Size 虚拟耗用内存(包含共享库占用的内存) RSS Resident Set Size 实际使用物理内存(包含共享库占用的内存) PCY 调度策略优先级,SP_BACKGROUND/SP_FOREGROUND UID 进程所有者的用户id Name 进程的名称
具体信息可以查看源代码中: xx\system\core\toolbox\top.c
4.结尾
最后附上相关的日志和已经编译好的procrank的库和可执行文件,由于涉及到具体的这里就不上传了