从源码角度看Android进程管理

简介

之前写过一篇Android进程保活原理与优先级调度机制的博客,与这篇要写的内容相仿。之前写过一篇Android进程保活原理与优先级调度机制的博客,与这篇要写的内容相仿。不同于之前的文章,本篇更多的是提炼、归纳、总结。

主要内容:

  • 从底层到上层解读Android进程的实现
  • 总结Android创建进程流程、进程查杀场景以及force-stop的功能
  • 最新发布的Android P在应用进程管理上的最新改动

Android应用进程管理发展史

将Android应用进程进行合理管理,因为直接和手机耗电挂钩,所以谷歌从Android 4.4版本就一直在做优化:

  • Lollipop: 推出 JobScheduler 机制。原理是将 service 的使用由APP主动变系统主动,也就是说APP使用JobScheduler的话,在时机合理的情况下系统才会主动调用bindService去触发APP的业务逻辑。Android 发展到今天的P,JobScheulder的地位越来越高
  • Marshmallow: 推出 Doze 模式,在灭屏后应用使用系统资源的能力将会收到限制,以此来达到省电的目的;推出 App Standby 机制,不分灭屏与开屏状态,标识出使用率很低的应用进行限制,此时的 standby 机制还不智能,对于应用的判断非黑即白,对省电的优化还很局限
  • Nougat: 开始明确的限制隐式广播,避免了典型的应用利用系统广播来起到保活作用的行为
  • Oreo: 对后台Service也开始进行了限制,
  • Pie: 引入体系更加完备的 App Standby 体系,根据等级来给应用划分到不同的 bucket中,以此来限制应用使用Alarm, JobScheduler, Network 的频率。值得注意的是,App Standby不仅仅是根据用户使用应用的状态来划分的,同时Google也会引入机器学习来预测应用所在bucket,以此来管理应用进程使用资源的能力,起到省电的目的。

Linux 进程概念

什么是进程?大家说法不一但是含义类似,《Linux 内核源代码情景分析》一书给出了”进程四要素”:

  1. 有一段程序供其运行
  2. 拥有专用的系统堆栈空间
  3. 在内核存在对应的进程控制块
  4. 拥有独立的用户存储空间

只有满足这四条才能够被称为进程。如果满足了前三条但是不满足第四条,我们称之为线程。这里需要强调下,linux中进程与线程都是使用 task_struct 来表述,区别在于进程是被 fork 生成的,而线程是被 clone 而成的。进程拥有独立的用户空间,而线程是同其它线程共享存储空间的。

task_struct

task_struct 又称进程控制块,主要用来描述进程的结构,包含以下主要信息:

  • 进程的标志符,如pid,uid等
  • 进程的状态,如state, exit_state, prio等
  • 进程间的关系,如parent, children的呢
  • 进程拥有的资源,如mm,stack,file等
  • 信号处理函数,如signal, sighand等

Android 进程的启动与查杀手段

进程启动

之前的几篇文章里,我对四大组件的相关启动流程都有过源码级的分析,具体相关的细节,大家可以看看以前的文章。

以进程的角度来看,四大组件之所以得此称号,除了和安卓上的普通业务息息相关外,另一个重要的成份在于唯有四大组件的启动,安卓应用才能够在 java 层创建一个新的进程。如上图中所示的APP的4个方法,当调用binder call到system_server端的AMS,在相应的方法中,如果AMS监测到要被启动的组件所在进程尚未被启动,那么AMS会先去启动进程,当启动成功后才会去运行这些组件。

关于进程的启动细节,大家可以参考我之前的一篇 AMS.startProcessLocked 的文章。

进程查杀

上图是我总结的目前 Android 可供主动调用的查杀进程接口,主要包含这几类:

  • 单独杀死一个进程,如 killApplication, killProcess
  • 根据优先级杀死应用的所有进程,高优先级的进程不会被杀,典型的如 killBackgroundProcesses
  • 根据进程标志符批量杀进程,如 killPids, killUid, 但是注意的是这些查杀方法并不会杀高优先级进程
  • 最后是堪称 Android 世界的核武器 force-stop,它会杀死所有进程并且会清除应用所有组件信息,包括 Alarm, Notification

Android P 新变化

最近 Google I/O 也在发布,AI 不出意外的是此处重点中的重点。关于进程方面,主要有以下改进:

  • 引入新的省电机制:App Standby Buckets,用来根据用户使用应用的状态、AI 模型的预测,来决定应用该分配到那个分组里。根据分组来限制APP使用资源的能力,以此来实现省电。不同与M引入的App Standby,这次的新机制更加强大。
  • targetSdkVersion的强制要求。因为大多数Android上的限制是N,O,P这三个版本做的,所有谷歌方面急切的希望应用能够提升targetSdkVersion,根据GooglePlay的要求,2018年8月中旬就要强制要求APP提升targetSdkVersion到26了。

应用状态引起App Standby Bucket变化

这块是我大致写的总结,可以先参考着看看。总的来说,这项服务的实现主要是在UsageStatsService来做的,数据基本上是从AMS, NMS这些和用户交互密切的服务传输过来的。

App 所处的 bucket 不同,对 Job, Alarm等的影响可以参考:

Bucket Jobs Alarm Network
Active 不限制 不限制 不限制
Working Set 每2小时 每6分钟 不限制
Frequent 每4小时 每30分钟 不限制
Rare 每24小时 每2小时 每24小时

AI的引入

关于AI方面的服务,安卓目前是以Device Health Services的形式,提供了一个apk com.google.android.apps.trubo来预测应用所在bucket的,这个包中包含诸多ML模型。

总结

这篇文章主要是总结下安卓进程管理由Linux到Android framework上层,细节性的代码分析可以参考我以前的文章

扫码支持0.99元,您的支持将鼓励我继续创作!