问题
曾经Android 的开机速度慢这一现象一直受人诟病,在实际工作中又可以在哪些地方做一些优化呢?
- ZygoteInit 的 main 函数中 preloadClasses 加载了一千多个类,这耗费了不少时间。
- 开机启动时,会对系统内所有的 apk 文件进行扫描并收集信息,这个动作耗费的时间非常长。尽量减少system内置app数量,或者对内置应用进行 LOCAL_DEX_PREOPT := true 配置生成odex。
- SystemServer 创建的那些 Service,会占用不少时间。在init.rc或框架层系统服务中去掉一些不需要加载的服务。
- 去掉系统中不必要的log打印,尽量编译user版本。
第一个问题,如何减少 preloadClasses 的时间。其实,这个函数是可以去掉的,因为系统最终还是会在使用这些类时去加载,但这样就破坏了 Android 采用 fork 机制来创建 Java 进程的本意,而 fork 机制的好处是显而易见的:
- zygote 预加载的这些 class,在 fork 子进程时,仅需做一个复制即可。这就节约了子进程的启动时间。
- 根据 fork 的 copy-on-write 机制可知,有些类如果不做改变,甚至都不用复制,它们会直接和父进程共享数据。这样就会省去不少内存的占用。
方案
开机速度优化是一项比较复杂的研究,目前有人使用 Berkeley Lab Checkpoint/Restart (BLCR) 技术来提升开机速度。这一技术的构想其实挺简单,就是对系统做一个快照,将系统当前信息保存到一个文件中,当系统重启时,直接根据文件中的快照信息来恢复重启之前的状态。当然想法很简单,实现却是很复杂的,仅供一个思路。
不过,随着手机Soc运算性能迭代提升、内存不断扩容等硬件性能提升,Android系统的开机速度也随之提升了很多,用户更多关心的是应用程序的启动速度,而非开机速度,毕竟很多人买了手机后除了系统升级时候很少关机/重启。