android java进程管理(六)之apk进程的回收

来源:互联网 发布:淘宝多肉种子哪家好 编辑:程序博客网 时间:2024/06/05 04:25

apk进程的回收

进程的回收就是进程占用资源的回收,进程占用的资源分两个部分:一是进程本身运行的实体,二是系统管理进程占用的资源,从(进程管理(四)之进程记录表)小节中发现,系统管理进程占用的最重要的资源就是那些ProcessRecord容器和内部四大组件记录表的容器,大家可以在回顾一下进程管理(四)小节。

我们先分析一下系统管理进程占用的资源是如何回收的,android提供了三个级别的方法,下面看一下每一级别的方法都释放了哪些资源:

第一级别的方法

cleanUpApplicationRecordLocked()
参数介绍:
1.ProcessRecord app:回收进程的进程记录表
2.boolean restarting:是否处于重启执行过程中
3.boolean allowRestart:是否允许重启
4.int index:目前系统中值都是为-1,属于无效值,目前可以忽略不计
5.boolean replacingPid:是否从进程名字容器中清除
返回值:
如果方法中重启进程,返回true,否则返回false

cleanUpApplicationRecordLocked()除了释放进程的部分资源,而且具有重启进程的能力,也就是说方法内部会判断是否需要重启进程,如果需要的话,触发启动进程流程,下面我们来具体看一下方法的执行:

  • 1.从mProcessesToGc 和mPendingPssProcesses 容器移除
  • 2.回收对话框资源
  • 3.回收记录package信息的容器
  • 4.断开binder讣告连接
  • 5.调用ActiveServices::killServicesLocked()回收组件ServiceRecord资源和绑定服务客户端ConnectionRecord资源
  • 6.回收发布的ContentProvider(ContentProviderRecord)资源
  • 7.回收正在启动的ContentProvider的资源
  • 8.回收ContentProvider(ContentProviderConnection)客户端的资源
  • 9.回收广播接收器的资源
  • 10.从mProcessesOnHold容器移除
  • 11.如果需要重启进程的话,调用startProcessLocked()启动进程,否则的话从mPidsSelfLocked容器中清除和将pid设置为0

注意:如果是第二级别的方法handleAppDiedLocked()调用的话,还会触发从mProcessNames容器移除

如果不考虑重启的情况的话,对于组件来说,这个方法回收除了ActivityRecord的所有的组件资源,ProcessRecord容器的话临时性容器回收了三个,永久性容器回收了一个,还剩下mProcessNames mLruProcesses mPersistentStartingProcesses 和mRemovedProcesses 这个特别容器共四个容器,第9步骤中,设置pid为0很重要,这个和mRemovedProcesses有关,介绍第三级别的方法是在介绍。

第二级别的方法

handleAppDiedLocked()
参数列表
1.ProcessRecord app:回收进程的进程记录表
2.boolean restarting:进程在重启的过程中调用这个方法
3.boolean allowRestart:是否允许重启进程
返回值:
无返回值

handleAppDiedLocked()方法会调用第一级别的方法,在第一级别基础上,有增加了一些资源的回收,下面我们来看一下调用流程:

  • 1.调用cleanUpApplicationRecordLocked()回收一部分进程资源
  • 2.如果第一级别返回false并且restarting也为false,调用removeLruProcessLocked()方法移除mLruProcesses容器
  • 3.调用ActivityStackSupervisor::handleAppDiedLocked()回收ActivityRecord资源
  • 4.确保UI 正常

这个方法回收了所有的组件资源,容器的话还剩下mProcessNames mPersistentStartingProcesses 和mRemovedProcesses 这个特别容器共三个容器

第三级别的方法

removeProcessLocked()
参数列表
1.ProcessRecord app:回收进程的进程记录表
2.boolean callerWillRestart:执行完这个方法是否要重启进程
3.boolean allowRestart:是否允许重启进程
4.String reason:移除原因,用于调试
返回值:
进程是否需要重启

removeProcessLocked()的执行流如下:

  • 1.调用removeProcessNameLocked()方法,从mProcessNames容器移除
  • 2.如果pid有效apk进程的话(pid > 0并且不是system_server进程的pid),kill进程然后调用第二级别的方法回收进程资源
  • 3.如果pid无效的话,加入mRemovedProcesses容器,什么时候无效?上面第一级别的方法中我们提到如果进程不重启的话,pid会设置为0,就代表无效,所有如果第一级别的回收方法已经被调用过的话,就会运行到这里,在此有一点需要强调一下:系统提供的这个三个级别的进程回收方法,我们是不能假设调用逻辑的,也就是说这个方法都应该是可重入的,对上层调用逻辑我们假设的越少,这样的低层地的方法设计就是越完美的。

三个方法基本介绍完了,还剩两个容器mPersistentStartingProcesses 和mRemovedProcesses,对于mRemovedProcesses,第三个方法介绍过,属于保存无效的进程记录表,不再这三个方法中处理,那么mPersistentStartingProcesses呢?这个容器保存的是启动中的persistent进程,这样子的进程是必须启动的,所以在启动的过程中移除即可,到此为此,所有的组件和容器全部回收完毕。

从以上的流程来看,removeProcessLocked()比handleAppDiedLocked()本质上只多做了一件事:就是kill进程,对就是这个kill,回收的就是进程本身运行实体

一个进程的退出需要分两个步骤来理解,一个是被kill(回收进程本身运行实体),另一个是回收进程占用的系统资源,所以如果这两个过程同步进行的话,就调用第三级别方法(removeProcessLocked()),如果想要异步执行的话,只需要kill进程,然后通过binder服务的讣告机制,使用第二级别的方法(handleAppDiedLocked())回收进程占用的系统资源。

1 0