Android提高启动速度的实现方法
首先看一下Android系统的启动流程:
bootloader
引导程序
kernel
内核
init
init初始化(这个大家都比较熟悉了,不要多说)
loads several daemons and services, including zygote
see /init.rc and init.<platform>.rc
zygote
这个是占用时间最多的,重点修理对象
preloads classes
装载了一千多个类,妈呀!!!
starts package manager 扫描package(下面详细介绍)
service manager
start services (启动多个服务)
从实际的测试数据来看,有两个地方时最耗时间的,一个是zygote的装载一千多个类和初始化堆栈的过程,用了20秒左右。另一个是扫描
/system/app,
/system/framework,
/data/app,
/data/app-private.
这几个目录下面的package用了大概10秒,所以我们重点能够修理的就是这两个老大的。
一、首先是调试工具的使用,可以测试哪些类和那些过程占用了多少时间,
主要工具为
stopwatch
Message loggers
grabserial
printk times
logcat
Android自带
bootchart
strace
AOSP的一部分(Eclair及以上版本)
使用例子
在init.rc中为了调试zygote
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server改为
service zygote /system/xbin/strace -tt -o/data/boot.strace /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
method tracer*
ftrace*
详细使用可看提供的文档和网页介绍
上面的工具如果不用详细的分析不一定都用到,也可以使用logcat就可以,在代码中加一点计算时间和一些类的调试信息也可以达到很好效果。
二、zygote 装载1千多个类
首先,我们可以添加一点调试信息,以获得具体转载情况。
diff --git a/core/java/com/Android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 404c513..f2b573c 100644
--- a/core/java/com/Android/internal/os/ZygoteInit.java
+++ b/core/java/com/Android/internal/os/ZygoteInit.java
@@ -259,6 +259,8 @@ public class ZygoteInit {
} else {
Log.i(TAG, "Preloading classes...");
long startTime = SystemClock.uptimeMillis();
+ long lastTime = SystemClock.uptimeMillis();
+ long nextTime = SystemClock.uptimeMillis();
// Drop root perms while running static initializers.
setEffectiveGroup(UNPRIVILEGED_GID);
@@ -292,12 +294,24 @@ public class ZygoteInit {
if (Config.LOGV) {
Log.v(TAG, "Preloading " + line + "...");
}
+ //if (count%5==0) {
+ // Log.v(TAG, "Preloading " + line + "...");
+ //}
+ Log.v(TAG, "Preloading " + line + "...");
Class.forName(line);
+ nextTime = SystemClock.uptimeMillis();
+ if (nextTime-lastTime >50) {
+ Log.i(TAG, "Preloading " + line + "... took " + (nextTime-lastTime) + "ms.");
+ }
+ lastTime = nextTime;
+
if (Debug.getGlobalAllocSize() > PRELOAD_GC_THRESHOLD) {
if (Config.LOGV) {
Log.v(TAG,
" GC at " + Debug.getGlobalAllocSize());
}
+ Log.i(TAG,
+ " GC at " + Debug.getGlobalAllocSize());
runtime.gcSoftReferences();
runtime.runFinalizationSync();
Debug.resetGlobalAllocSize();
上面+代表添加的代码,这样就可以很容易的得到在装载类的过程中具体装载了哪些类,耗费了多久。具体装载的类在文件platform/frameworks/base/ preloaded-classes
内容类似:
Android.R$styleable
Android.accounts.AccountMonitor
Android.accounts.AccountMonitor$AccountUpdater
Android.app.Activity
Android.app.ActivityGroup
Android.app.ActivityManager$MemoryInfo$1
Android.app.ActivityManagerNative
Android.app.ActivityManagerProxy
Android.app.ActivityThread
Android.app.ActivityThread$ActivityRecord
Android.app.ActivityThread$AppBindData
Android.app.ActivityThread$ApplicationThread
Android.app.ActivityThread$ContextCleanupInfo
Android.app.ActivityThread$GcIdler
Android.app.ActivityThread$H
Android.app.ActivityThread$Idler
而这个文件是由文件WritePreloadedClassFile.java中
补充:移动开发 , Android ,