一、Android内存管理概述:为什么需要低内存杀进程?

大家好,我是你们的讲师。今天咱们聊聊Android内存管理,特别是那个让无数开发者又爱又恨的——低内存杀进程机制。

先问个问题:你手机用着用着,切回微信发现要重新加载,或者游戏打着打着突然退出了。这是为什么?

说白了,就是系统在“抢内存”。Android不像iOS那样有严格的后台管理,它允许应用在后台待着。但内存就那么大,后台应用多了,前台应用就不够用了。这时候,系统就得做出选择——杀掉一些进程,腾出空间。

我刚开始做Android系统开发时,也纳闷过:为什么不能像PC那样用虚拟内存?后来才明白,移动端有移动端的苦衷。

1.1 Android内存压力来源

内存压力从哪来?我把它分成三类:

  • 应用层压力:每个App都在抢内存。你装100个应用,每个后台占50MB,那就是5GB。我见过一个社交App,光图片缓存就吃了300MB。
  • 系统服务压力:System Server、SurfaceFlinger这些系统进程,它们也得活着。系统服务一旦挂了,手机就重启了。
  • 硬件限制:手机不像PC能插内存条。出厂多大就多大,用户没法升级。4GB内存的手机,现在跑个微信+抖音就快满了。

核心观点:Android杀进程不是bug,是feature。它是在有限资源下,保证前台体验的无奈之举。

1.2 为什么不用Linux的OOM Killer?

你可能会问:Linux内核不是有OOM Killer吗?为什么Android还要自己搞一套?

嗯,这里要注意。Linux的OOM Killer是“最后手段”,它是在内存彻底耗尽时才触发。而且它杀进程的方式很粗暴——谁占内存多杀谁。

但Android不一样。它需要更精细的控制:

  • 前台应用优先级最高,不能随便杀
  • 后台服务可以杀,但得按优先级来
  • 缓存进程可以优先杀,因为它们随时能重启

我曾在项目中遇到过一个问题:某个视频App在后台播放音乐,结果被OOM Killer干掉了。用户投诉说“听着歌突然断了”。这就是因为OOM Killer不懂Android的优先级。

所以Android搞了一套自己的机制——Low Memory Killer(LMK),后来演变成了现在的LMKD。它根据进程的“重要性”来决定杀谁,而不是单纯看内存占用。

1.3 内存压力的分类与等级

Android把内存压力分成了几个等级,就像台风预警一样:

压力等级 触发条件 系统行为
轻度 可用内存低于阈值1 开始回收缓存页、压缩内存
中度 可用内存低于阈值2 开始杀缓存进程、后台服务
重度 可用内存低于阈值3 开始杀前台服务、甚至部分可见进程
临界 内存几乎耗尽 触发内核OOM Killer,可能杀任何进程

这些阈值不是固定的。不同厂商、不同机型会调优。我记得有一次帮客户调试,发现某款手机在内存还剩800MB时就开始杀进程了。用户觉得“明明还有内存,为什么卡?”其实是因为厂商把阈值设得太保守了。

避坑指南:我曾经调试过一个案例,App在后台频繁被杀死。后来发现是因为App申请了太多匿名共享内存(ashmem),导致系统误判为内存压力大。解决方案是限制App的ashmem使用量。

1.4 杀进程的代价

杀进程不是免费的。每次杀进程都有代价:

  • 用户体验代价:App重启、数据丢失、加载变慢
  • 性能代价:重新创建进程、加载资源,CPU和IO开销
  • 电量代价:频繁杀进程和重启,反而更耗电

所以Android在杀进程这件事上,一直在做权衡。杀得太狠,用户骂;杀得太松,系统卡。

我个人习惯是:在系统调优时,先观察一段时间的kswapd和lmkd日志,看看内存压力到底在哪。不要盲目调阈值。

1.5 本章小结

好了,咱们总结一下:

  • Android杀进程是因为内存有限,必须保证前台体验
  • 它比Linux的OOM Killer更智能,能按优先级杀进程
  • 内存压力分等级,系统在不同等级下采取不同措施
  • 杀进程有代价,调优时要权衡利弊

下一章,咱们会深入LMK的源码,看看它到底是怎么决定“杀谁”的。你想想看,一个系统要在一毫秒内做出生死判决,是不是挺刺激的?

注意:本章内容基于Android 12+的LMKD机制。不同版本可能有差异,但核心思想一致。