android内存机制 演变,Android的lowmemorykiller演变分析

在学习Android的lowmemorykiller机制过程中,发现从KK到L再到M有一些新的变化,因此有必要进行一下总结。在开始分析前先厘清一些基础概念,便于描述的展开和结论的形成。本文内容并没涉及太多具体实现细节,目的只是为实际的开发提供纲领性指导意见。

一、基本概念

1、PageCache:Linux内核为加快文件预取而采用的特有机制(参考引用一),就是尽可能的把空闲内存用于缓存最近访问过的磁盘文件数据。由于会占用大量的空闲内存,在某种情况下就会导致OOM的发生。Linux内核的内存管理是很重要的部分,需要花很多时间和精力来学习(参考引用二)。

2、OOM:即“Out of Memory”的缩写,这个其实是标准Linux内核的一种内存管理机制,在内存不足或无法分配(大)内存的时候会触发此机制,来完成内存的回收。具体到代码级别,内存页面回收机制是Cache Shrinker,通过内核线程kswapd监控内存页面情况和触发Shrinker回调函数进行内存页面回收。

3、lowmemorykiller(简称LMK,下同):是Android基于标准Linux内核OOM机制修改而来,最初的方式是通过在内核实现一个staging形式的驱动,在此驱动中注册Shrinker回调函数和实现应用策略,剩下的工作就是定时检查及判断是否需要回收(或定时检测和内核触发相结合???)。关于OOM和LMK详细信息可参考引用三。

4、CGroup:简单的说就是对进程线程使用各种系统资源的分组管理和控制,包括如CPU、IO、MEMORY,等等。

二、LMK实现演变

1、在Android的KK(或之前)版本中,LMK机制和策略都是在内核空间驱动中实现的,驱动提供两个sys文件结点给AMS用于设置触发内存回收的阀值。

2、在Android的L(或之后)版本中,引入了一个处于用户空间的守护进程lmkd(参考引用四),LMK机制和策略的实现多了一种选择---即可在用户空间完成。但不管是旧的还是新的方式,原来由AMS完成的设置工作都通过socket方式传递参数给lmkd来实际完成。这样一来AMS与内核的耦合性进一步降低,把精力关注于activity的管理。

三、lmkd进程分析

关于lmkd的作用在修改日志中很明确:

Author: Todd Poynor

Date: Tue Jul 9 19:35:14 2013 -0700

Add lmkd low memory killer daemon

Move kernel low memory killer logic to new daemon lmkd. ActivityManager

communicates with this daemon over a named socket.

为什么导入lmkd,根据我的经验分析一来在用户空间实现策略更容易优化和管控,二来LMK驱动是Android特有的东西不太容易进入Linux内核的正式驱动列表(一直是staging形式)。在google groups的一个讨论组(android-platform)的贴子中也提到了类似的观点(引用五,需自备楼梯):

Dual supported in L. For example N9 released with lmk due to its advanced architecture

giving an edge to lmk over lmkd. Low memory killing is an important feature on all

Android Devices and its tuning and optimization is a requirement to provide the best

and balanced user experience. The option of either improves the tuning options of the

device manufacturers. Support for lmk scales because of its inclusion upstream in the

kernel. Our goal is to improve lmkd as an optimized replacement with algorithms that

live well in the android ecosystem. 考虑到使用Android版本内核的差异性,lmkd进程的实现是兼容了新旧两种不同方式的: (1) 使用LMK驱动(旧的方式),配置阀值参数保存在驱动中,LMK策略由驱动实现,内核通过Shrinker机制触发策略执行; (2) 不使用LMK驱动(新的方式),配置阀值参数保存在lmkd进程中,LMK策略由lmkd进程实现。但为了触发策略的执行,必须定制内核加入memory cgroup,通过监控memory pressure event来触发LMK策略执行; 根据lmkd的实现意图,理论上来说应该使用第二种方式才对; 四、memory pressure event         这个其实也是标准Linux内核在2013年4月就已经实现的功能(提交者为Anton Vorontsov,patch的标题是“memcg: Add memory.pressure_level events”)。基于memory cgroup,内核可以分析当前内存的使用情况压力等级(low、medium、critical),并把相关信息通过eventfd方式通知给用户空间的监听者执行相关动作(如内存回收)。                 memory pressure event的实现(引用六)经过四次review(多人参与讨论,包括Linus Torvalds、Andrew Morton等大boss)才进入mainline,不得不配服国外开源环境的活跃及严谨治学态度。在这一系列讨论中也有人提及Android相关考虑,作者的想法就是实现一个通用的方式(包括对Android等移动设备支持)。         从lmkd是2013年7月提交时间来看,借助memory pressure event方式的实现,google终于如愿以标准Linux内核方式消除了staging形式LMK驱动这个“鱼刺”。至于使用memory pressure event方式的内存回收效率及实际效果如何,未进行相关测试前就不得而知了。 五、引用 1、linux的page cache策略 http://blog.csdn.net/fall221/article/details/46290563 2、linux内存管理各文件简介 http://blog.csdn.net/u011955950/article/details/18860379 3、android Low Memory Killer介绍 http://blog.csdn.net/hgl868/article/details/6744883 4、Android——内存管理-lowmemorykiller 机制 http://blog.csdn.net/jscese/article/details/47317765 5、why lmkd and logd are created to move log and lmk from kernel to userspace in L? https://groups.google.com/forum/#!topic/android-platform/PW85I7qRBP8 6、memcg: Add memory.pressure_level events https://patchwork.kernel.org/patch/2123031/ https://patchwork.kernel.org/patch/2161601/ https://patchwork.kernel.org/patch/2318281/ https://patchwork.kernel.org/patch/2384491/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值