Android 进程知识
进程优先级
Android系统的进程总共分为5级:
-
Forground Process
前台进程.一般情况下,同一时间只有少数几个前台进程, 当满足一下几个条件时, 一个进程会被当做前台进程:
- 进程持有一个正在同用户的进行交互的
Activity
或者说Activity
的onResume
方法被调用了 - 进程持有一个
Service
, 该Service
与正在同用户交互的Activity
绑定 - 进程持有一个
Service
,该Service
调用了startForground
方法 - 进程持有一个正在执行某一个生命周期回调方法(
onCreate, onStart, onDestroy
)的Service
- 进程持有一个正在执行
onReceive
的BroadcastReceiver
-
Visible Process
可见进程.此时进程并没有任何前台组件,但是仍然可以影响用户在屏幕上的感知, 如果满足以下条件,则进程会被当做可见进程:
- 进程持有一个并不在前台的
Activity
,但是该Activity
仍然可见(即onPause
方法被调用),典型的例子是弹出一个Dialog
时,Activity
的onPause
方法被调用但仍可见 - 进程持有一个同可见
Activity
绑定的Service
-
Service Process
服务进程.一个进程持有一个通过startService
方法启动的Service
且并不满足上述两类进程的任何条件时会被当做服务进程.一般情况下,服务进程多用于播放音乐,下载数据等操作,系统一般情况下会保证服务进程的存活除非内存已不足够保证所有前台进程和可见进程存活时才会杀死服务进程 -
Background Process
后台进程.一个进程持有一个不可见的Activity
即onStop
方法被调用的时候该进程会被当做后台进程. 后台进程不直接影响用户体验,系统可以在任何时候杀死后台进程以回收内存.一般情况下,会有多个后台进程存在,这些进程会记录在一个LRU
列表中, 该列表用来保证最近可见的进程会被最后杀死 -
Empty Process
空进程.一个进程没有任何活动组件时被称为空进程. 空进程存活的唯一原因是提供缓存功能, 以缩短下次的启动时间, 为使总体系统资源在进程缓存和底层缓存之间保持平衡,系统往往会终止这些进程
Android对一个进程优先级划分的依据是进程内的组件当前活跃的重要性,举例来说,一个进程持有一个Service
和一个Visible Activity
, 则该进程会被当做Visible Process
而不是Service Process
.
另外,一个进程优先级的划分也可能依赖于其他进程,比如A进程提供服务给B进程,那么A进程的优先级就不可能低于B进程.
因为服务进程优先级高于后台进程, 如果一个Activity
需要启动一个耗时很长的操作,最好是启动一个Service
来完成这些操作而不是在Activity
中使用线程, 这样的话,耗时的操作就会一直存在除非服务进程被杀死, 如果是在Activity
中使用线程的话,则当进程变为后台进程时,耗时操作很可能会随着进程被杀死而中断,因为此时进程属于后台进程,随时都可能被系统杀死.
进程回收策略
Android对于内存的回收,主要依靠LowmemoryKiller
完成, 是一种根据OOM_ADJ
阈值级别触发相应力度的内存回收的机制
OOM_ADJ
的说明如下:
ADJ级别 | 取值 | 解释 |
---|---|---|
UNKNOWN_ADJ | 16 | 一般指将要缓存进程,无法获取确定值 |
CACHED_APP_MAX_ADJ | 15 | 不可见进程的adj最大值1 |
CACHED_APP_MIN_ADJ | 9 | 不可见进程的adj最小值2 |
SERVICE_B_AD | 8 | B List中的Service(较老的,使用可能性更小) |
PREVIOUS_APP_ADJ | 7 | 上一个App的进程(往往通过按返回键) |
HOME_APP_ADJ | 6 | Home进程 |
SERVICE_ADJ | 5 | 服务进程 |
HEAVY_WEIGHT_APP_ADJ | 4 | 后台的重量级进程, /system/rootdir/init.rc文件中设置 |
BACKUP_APP_ADJ | 3 | 备份进程 |
PERCEPTIBLE_APP_ADJ | 2 | 可感知进程,比如后台音乐播放 |
VISIBLE_APP_ADJ | 1 | 可见进程 |
FOREGROUND_APP_ADJ | 0 | 前台进程 |
PERSISTENT_SERVICE_ADJ | -11 | 关联着系统或persistene进程 |
PERSISTENT_PROC_ADJ | -12 | 系统persistent进程,比如telephony |
SYSTEM_ADJ | -16 | 系统进程 |
NATIVE_ADJ | -17 | native进程(不被系统管理) |
HEAVY_WEIGHT_APP_ADJ
以上(包含HEAVY_WEIGHT_APP_ADJ
)以上的部分代表比较容易被杀死的Android进程,即(OOM_ADJ
>= 4), OOM_ADJ
从3到0之间的进程是不容易被杀死的. LMK回收内存时会根据进程的优先级优先杀死OOM_ADJ
比较大的进程,对于优先级相同的进程则进一步受到进程所占内存和进程存活时间的影响.
killBackgroundProcess
只能杀死OOM_ADJ >= 4
的进程