Android内存管理机制之幽灵杀手——LowMemory Killer

96
尹star
2015.11.15 09:52* 字数 2010

Android内存管理其实是一个非常复杂和庞大的话题,Android系统的内存管理机制有:Lowmemory Killer机制,Ashmem机制,Pmem/Ion机制及Native内存管理和Dalvik内存管理和Jvm垃圾回收机制。我们今天只讲Lowmemory Killer机制。

Android系统是基于Linux 内核开发的开源操作系统,而Linux系统的内存管理有其独特的动态存储管理机制。不过Android系统对Linux的内存管理机制进行了优化,Linux系统会在进程活动停止后就结束该进程,而Android把这些进程都保留在内存中,直到系统需要更多内存为止。Android是一个多任务系统,也就是说可以同时运行多个程序,一般来说,启动运行一个程序是有一定的时间开销的,因此为了加快运行速度,当你退出一个程序时,Android并不会立即杀掉它,这样下次再运行该程序时,可以很快的启动。随着系统中保留的程序越来越多,内存肯定会出现不足,这个时候Android系统开始挥舞屠刀杀进程。Android系统中杀进程的这个刽子手被称作"Lowmemory Killer",也就是我们要探讨的这货,它是在Linux内核中实现的。现在我们已经知道杀手是谁了,那么问题来了,杀谁?

我们已经清楚内存不足时Lowmemory Killer会杀掉某些进程,那我们来看一下Android系统都有哪些进程(按被杀死的可能性从低到高排列)。

1:前台进程(Forground App)

目前正在屏幕上显示的进程和一些系统进程,几乎没有被杀死的可能性,代表进程:你目前正在读这篇文章所用的应用。

2:可见进程(Visble App)

这部分进程虽然不在前台,但与我们的使用也密切相关,我们也不希望它们被终止,通常情况下不会被杀死,代表进程:输入法。

3:次要服务(Secondary Server)

这部分服务虽然属于次要服务,但很一些系统功能依然息息相关,我们时常需要用到它们,所以也太希望他们被终止。代表进程:联系人内部存储。

4:后台进程(Hidden App)

就是我们通常意义上理解的启动后被切换到后台的进程,如浏览器,阅读器等。当程序显示在屏幕上时,他所运行的进程即为前台进程(Foreground),一旦我们按Home返回主界面(注意是按Home,不是按Back),程序就驻留在后台,成为后台进程(Background)。

5:内容提供者(Content Provider)

没有程序实体,仅提供内容供别的程序去用的,比如日历供应节点,在终止进程时,这类程序应该有较高的优先权。

6:空进程(Empty App)

在程序退出后,依然会在进程中驻留一个空进程,这个进程里没有任何数据在运行,作用往往是提高该程序下次的启动速度或者记录程序的一些历史信息。这部分进程无疑是应该最先被终止的。

Android系统共有六类进程,当内存发生不足时最先杀死的是空进程,如果杀死空进程后依然无法保证足够的Ram,屠刀将挥向内容提供者,再不够杀后台进程,以此类推。当然前台进程,可见进程,次要服务这三个被杀死的肯能性很小。我们已经搞清楚了杀谁的问题,那么问题又来了,什么时候杀?

你可能会说就是Ram不足的时候杀呗,那到底什么时候视为Ram不足呢。Android系统有一个规则来回收内存,进行内存调度有个阀值,只有低于这个阀值系统才会按一个顺序来关闭系统认为最不重要的进程,释放Ram空间。为了更有说服力,我们干脆来看看这个阀值到底是多少,不过要先获取手机的Root权限,打开你的Android手机Sys/Module/Lowmemorykiller/Parameters/Minfree的这个目录文件,阀值就被写在这里。以我手里这台Nexus7为例,我得到一串数字:5418,7224,14448,36120,45150,54180,这串数字是什么意思,我猜应该是摩斯密码吧,开个玩笑,当然不是,这六个数字分别代表了6种进程(对应上文的顺序)可能被杀死的剩余内存最小阀值,这串数字的单位是Page,1Page=4Kb,我们做一下转换就54180Page=211Mb, 就是说当运行内存小于211Mb的时候,Lowmemory Killer就要杀死Empty App。Content Provider:45150Page=176Mb,当运行内存小于176Mb的时候,Lowmemory Killer不光要杀死Empty App,还要杀死Content Provider。Hidden App:141Mb,Secondary Server: 56Mb,Visible App:28Mb,Forgound App:21Mb,以此类推。

我们可以获取手机系统的内存调度阀值,那么用户可不可以更改这个阀值?当然可以,Android最大的魅力就在于能满足你的无限幻想,只要你想做,总是有办法的。打开Minfree文件,如果你是个Android骨灰级玩家,你甚至可以手动修改文件内的阀值大小,高级玩家也可以借助工具自行修改,初级玩家还是洗洗睡了吧。修改阀值有什么作用呢,这就好比一台车,你可以把避震调教的硬一点,来获得更精准的操控乐趣;你也可以把避震调教的软一点,来获得更舒适的驾控体验。再说回手机,我们可以调大阀值,让系统一直运行在一个充裕的内存环境中,当然这个时候Lowmemory Killer可能要频繁工作,也会带来相对应的性能损耗。我们也可以调小阀值,让系统缓存更多的进程,这样下次打开应用的时候会更迅速,这里的缺点就是当可用内存比较少的时候打开一个大型应用,Lowmemory Killer会比较忙,用户的直观感觉就是有点卡。阀值设成多大,关键是找到一个适合自己的平衡点。手机出厂系统会有一串默认阀值,这串阀值应该是手机厂商调教过的一个比较舒适的平衡点了,一般情况下不建议用户自己手动修改。

最后再说一个问题,如何正确的使用Android手机?如果你是一个Android 用户,你肯定经常手动杀后台应用,因为你觉得他们会耗电,但事实上并没有,后台应用只是在内存中保存了一个运行状态,他们什么事都没干,当然也不会耗电(流氓应用和常驻内存的应用除外)。 你又会说即便不耗电,也占内存,占内存又有何妨,系统有自己的内存管理方式,你的手机系统里有个杀手  -----  Lowmemory Killer,这种事还是交给它来做吧。。。

Android
Web note ad 1