一:背景
Android为了加速进程的启动速度,在进程退出前台之后并不会立刻杀死进程,而是会尽可能的保留进程,当用户下次启动进程时,进程就会由冷启动变成温启动,启动速度大大加快。但后台进程过多时,会抢占CPU、memory等有限的系统资源,那么如果保证在不杀死进程的情况下,避免进程抢占系统资源呢?墓碑机制(进程冻结)应运而生。
二:功能详解
2.1 进程冻结原理
Android将进程按照优先级从高到低分为: 前台进程 -> 可感知进程 -> 服务进程 -> Cached进程。Freezer通过冻住cached进程来释放这些进程占用的系统资源。
2.2 进程冻结流程图
进程冻结的触发条件是进程优先级(adj)的改变,当有进程变成cache进程(adj>=900)时,就会触发cache进程的冻结。关于进程优先级的更新、计算等具体逻辑,可以参考Android进程管理-进程优先级(AndroidU)这篇文章,这里就不详细展开了。
2.3 进程冻结功能实现
2.3.1 进程冻结的初始化
2.3.1.1 SystemServer.run
Android启动,会调用到SystemServer.main,在main函数中会调用自身的run函数来启动各个系统服务。具体Android启动流程这里就不详述了,以后会出专门的文章来解析。
private void run() {
...
startBootstrapServices(t);//初始化引导类型系统服务
startCoreServices(t);//初始化核心系统服务
startOtherServices(t);//初始化其他系统服务
startApexServices(t);//初始化apex系统服务
updateWatchdogTimeout(t);//更新看门狗超时时间
...
}
2.3.1.2 SystemServer.startOtherServices
会调用ContentProviderHelper.installSystemProviders函数来初始化SettingsProvider
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
...
t.traceBegin("InstallSystemProviders");
//初始化SettingsProvider
mActivityManagerService.getContentProviderHelper().installSystemProviders();
// Device configuration used to be part of System providers
mSystemServiceManager.startService(UPDATABLE_DEVICE_CONFIG_SERVICE_CLASS);
// Now that SettingsProvider is ready, reactivate SQLiteCompatibilityWalFlags
SQLiteCompatibilityWalFlags.reset();
t.traceEnd();
...
}
2.3.1.3 ContentProviderHelper.installSystemProviders
会调用OomAdjuster.initSettings来初始化OomAdjuster
public final void installSystemProviders() {
...
mService.mOomAdjuster.initSettings();//初始化OomAdjuster
...
}
2.3.1.4 OomAdjuster.initSettings
会调用CachedAppOptimizer.init来初始化CachedAppOptimizer
void initSettings() {
mCachedAppOptimizer.init();
mCacheOomRanker.init(ActivityThread.currentApplication().getMainExecutor());
...
}
2.3.1.5 CachedAppOptimizer.init
会调用CachedAppOptimizer.updateUseFreezer来初始化进程冻结功能
public void init() {
...
updateUseFreezer();//进程冻结初始化
...
}
2.3.1.6 CachedAppOptimizer.updateUseFreezer
会先判断CACHED_APPS_FREEZER_ENABLED数据库的值,如果是disabled,会把mUseFreezer设置为false,接着会调用enableFreezer(false);直接返回false。
如果CACHED_APPS_FREEZER_ENABLED数据库的值是enabled或者use_freezer对应的DeviceConfig的值是true,则会调用isFreezerSupported函数判断驱动是否支持,接着更新Debounce超时时间(10s)。
如果mUseFreezer是true,调用enableFreezer来使能冻结功能,并启动CachedAppOptimizerThread线程来做进程冻结的操作。
private void updateUseFreezer() {
//获取CACHED_APPS_FREEZER_ENABLED数据库的值
final String configOverride = Settings.Global.getString(mAm.mContext.getContentResolver(),
Settings.Global.CACHED_APPS_FREEZER_ENABLED);
if ("disabled".equals(configOverride)) {//如果是disabled,则不支持进程冻结
mUseFreezer = false;
} else if ("enabled".equals(configOverride)
|| DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_NATIVE_BOOT,
KEY_USE_FREEZER, DEFAULT_USE_FREEZER)) {//如果CACHED_APPS_FREEZER_ENABLED数据库的值是enabled或者use_freezer对应的config的值是true
mUseFreezer = isFreezerSupported();//判断驱动支不支持Freezer
updateFreezerDebounceTimeout();//更新Debounce超时时间
updateFreezerExemptInstPkg();//将软件包标记/取消标记为自动安装