Android系统的问题分析笔记(3) - Android系统内存不足时的应对方案

问题

Android系统在内存不足时,会启用什么机制来腾出内存供使用呢?

方案

  尽管 Android 最大限度地利用了共享内存的优势,并佐以 KSM1 和ZRAM 等技巧,但没有真正的 swap 空间仍然是一个绕不过去的坎。这并不是 Android 设计上的缺陷,因为闪存芯片的刷写次数有一定的上限,所以闪存和 swap 就是没法一起使用。由于没有 swap,系统在任何时候都可能会出现物理内存耗尽的情况一一这是一个相当明确且现实的危险。
  Linux 内核有一个处理内存不足的机制 OOM(Out-Of-Memory,内存不足)。这个机制会在系统无法满足内存分配请求时被触发。不过在 Linux 中,它被触发的情况很少一一如果系统剩余物理内存空间低了的话,通常都有大量的 swap 空间可供页交换。所以只有当物理内存和 swap 空间都不足时,才会触发 OOM。
  OOM 并不是一个线程,它被实现为发生内存不足的情况时,要被执行的一系列代码。这些代码逐一遍历所有的进程,试图从中找出一个最合适杀掉的进程以在最大程度上缓解系统内存不足之苦。所有的进程都作为候选对象,在这个“死亡队列”中,以oom_score值(这是一个启发式的评分测试分值,具体评分测试的算法一直随着内核版本的更新而不断地调整)排序。这个分值也可以在/proc/pid/oom_score 这个只读的伪文件中读取到。
  oom_score 的问题在于:它好像并不是总能可靠地工作,常常会有无辜的进程被误杀掉(只是因为它在错误的时间得到了一个错误的 oom score 分值)。由于杀掉被选中的进程的操作 (实际上就是个 kill -9) 会被立即而果断地执行,所以“受害者”进程是无法做出任何反抗的。
  因此,Android App 的整个生命周期总是笼罩在一层随时随地会被莫名其妙地干掉的阴影中,它们只能使用一些回调函数来保存它们的状态(还是通过文档不详细的 android.os.Bundle),系统也只能保证:如果它被杀掉了,当它再次执行时,可以使用这个 bundle 中的信息恢复之前的状态。应用程序根本无法预测自己何时会被杀掉,甚至连自己会不会被杀掉也都无法预测。
  为了缓解一下这个评分方式引发的“宿命论危机”,Linux 提供了一种在用户空间中调整 oom_score 的方式,它就是/proc/pid/oom_adj 和(在比较新的内核版本中的)proc/pid/oom_score_adj 文件。这两个文件让用户空间里的进程能够给 oom_score 加上一个修正值:

  • 如果加上的是个负的修正值,就会把 oom_score 变小(因而会降低进程被杀掉的概率);
  • 如果加上的是个正的修正值,就会把 oom score 变大 (这对那些有自杀倾向的进程倒是蛮有效的…);

  Android 的系统进程使用这一机制,确保它们不会被杀掉:/init 和它根据各个rc 文件启动的同级进程,会在自己的 oom_adj 加上一个-16或-17 这样的修正值(这使得OOM 完全不会杀掉它们)。在比较新的内核里,它们给 oom_score_adj 加上一个-1000 的修正值,这会让它们的 oom_score 值接近于0。
  从坏的角度讲,为了防止这一功能被 App 滥用,Android 的 ActivityManager 会在应用生命周期里的不同阶段,自动重置oom_adj/oom_score_adj 中的修正值。在Android L 及以后的版本中,ActivityManager 是通过 lmkd 服务调整 OOM 分值的,因为oom_adj/oom_score_adj 文件只为 root 所有,而且也只有 root 才有写它的权限。可参考:Android 系统内的守护进程 - core类中的服务(3) : lmkd
  Android 提供的另一种预防措施是以 LowMemoryKiller (Imk)的形式给出的。这是一种抢在真正的OOM 被触发执行之前,先杀掉一些进程的防止 OOM 杀“好人”的 Android 技巧。从Android L 开始,init 只管确保 sysfs 中各个伪文件的访问权限的设置是正确的,设置 sysfs 中module/目录下的各个参数的任务就留给 lmkd 了。


  1. Linux 内核中的KSM (Kernel Samepage Merging,内核相同页合并)机制。这一特性使得内核能够 (通过比较 Hash 的方式)自动检查物理内存页中的数据是否相同一一相关物理内存页甚至可以还没被map 到某个虚拟内存地址上。如果找到了两个物理内存页中的数据是完全相同的,这两个页就会在引入了“写时复制”(copy-on-write) 的限制后,被合并。 ↩︎

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Android笔记系统是一种可以帮助用户记录、整理和分享笔记的应用程序。以下是一些常见的Android笔记系统的特点和功能: 1. 笔记编辑:大多数Android笔记系统都提供了基本的文本编辑功能,用户可以输入、编辑和保存笔记。一些系统还允许用户插入图片、附件和链接等元素,以丰富笔记内容。 2. 分类和标签:许多Android笔记系统允许用户将笔记进行分类和标签,以便更好地组织和查找。这有助于用户根据主题、日期或其他标准将笔记分组,以便快速找到所需的资料。 3. 笔记共享:一些Android笔记系统允许用户将笔记分享到社交媒体平台或与其他人共享。用户可以选择将笔记以链接、邮件或其他形式发送给朋友或同事,以便他们能够方便地查看和评论笔记。 4. 搜索功能:许多Android笔记系统提供强大的搜索功能,用户可以根据关键词、标签或分类快速找到所需的笔记。 5. 提醒和日历集成:一些Android笔记系统与日历应用程序集成,允许用户设置提醒,以便在特定日期或间提醒用户查看或更新笔记。 6. 云同步:大多数Android笔记系统都支持云同步功能,用户可以将笔记存储在云端,并在多个设备上访问。这有助于用户在不同设备之间同步笔记,并确保数据的安全性和可访问性。 7. 多平台支持:一些Android笔记系统还支持在多个平台上使用,包括iOS、Windows和Mac等。这为用户提供了更多的灵活性和选择。 总之,Android笔记系统为用户提供了一个方便、高效的方式来记录、整理和分享笔记。它们提供了各种功能和工具,以帮助用户更好地组织和查找信息,并与其他人共享和协作。选择一个适合自己的Android笔记系统,可以帮助您更有效地管理您的学习、工作或个人笔记

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小馬佩德罗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值