利用BLCR加快Android的启动过程

摘要:介绍了利用blcr对Android启动速度进行优化的原理、实施步骤和注意点,在虚拟机上验证获得缩短10秒以上启动时间。

关键词:blcr  android  启动速度   zygote   类加载

引言 随着google的android操作系统在手机、平板电脑等领域大量使用,android的启动速度慢也成为许多使用者抱怨的缺点。相比手机这类平时较少开关机的设备,平板电脑在实际使用中开关的频率相对频繁,开机速度是影响客户感受的一个重要因素。Android启动过程分为linux内核载入,文件系统挂接,zygote进程启动和软件包扫描几个主要过程。其中耗时大户发生在zygote的类载入和软件包扫描过程两处,只要减少这两处的时间,启动速度就会发生明显的改变。如何有效加快启动速度是众多android产品制造者都感兴趣的技术。本文就缩短android 启动过程中公用类加载部分的一种技术做介绍,利用该方法,在虚拟机实际测试获得良好的结果。

背景知识 Zygote是android中的核心进程,其负责android其他应用和服务的孵化,zygote启动过程慢的一个原因在于

启动过程中需要提前加载公用类(由文件preloaded-classes定义),这种加载是android设计人员特意根据linux和嵌入式系统特性设计的,网络上有人尝试将这些类的加载去除以加快开机速度,这种违背设计者初衷的方法被否决(参考1)。对于单个进程而言,如果使用到这些公共类,都必须完成对应类的载入并初始化,由于zygote是后续所有android的父进程,采用Class.forName处理的公共类会被载入到内存并完成静态初始化,提前加载可以避免每个子进程调用时候需要生成公用类的副本(linux Copy-on-write特点),进而减少内存占用量以及后续启动其他程序的花销。这个加载过程关系到后续的性能,所以不能简单的跳过。载入的过程主要是对内存的操作过程,其中包括了大量的内存分配释放过程,该过程由于有上千个类需要操作而变得耗时较长。在实际应用中,由于framework部分较少升级,故这些公共类是不会被动态删减,考虑到这些特点,采用check point方式每次直接将zygote还原到完成类加载的阶段避开频繁的类操作显然可以提高速度。

BLCR (Berkeley Lab Checkpoint/Restart)是应用于linux下的check point/restore 软件,它可以将正在运行于linux上的应用当前的运行点保存成为一个文件并且在以后的时间可以按照需要将该程序直接恢复到保存时候的状态。该软件官方网站在:。根据其FAQ介绍BLCR对保存和恢复的程序有部分限制:1 无法保存和恢复打开的sockets(TCP/IP,Unix domain等)2 无法保存和恢复Sys V IPC对象。3 在处理还没有回收僵尸子进程的父进程是需要注意。尽管有部分限制,只要在使用时候注意这些限制,利用其保存和恢复程序运行点和内存的能力完全可以避免程序每次不必要的初始化动作。Zygote在加载公共类前时候除了堆外其他资源使用很少,通过仔细的调整/恢复BLCR无法恢复的一些状态,是可以用check point形式来跳过类加载以缩短启动时间。 BLCR 包括内核驱动和应用库两部分,外部应用通过链接应用库和内核驱动进行交换实现应用的保存和恢复。下面就针对emulator下的android2.2介绍实现blcr的具体过程。

实施过称

一 软件准备:

blcr-0.8.2

android2.2 froyo

android-goldfish-2.6.29

pthread的补丁

编译android和内核在这里不详述,需要指出的有两点。

1 编译内核时候注意加入可加载模块支持(Enable loadable module support),缺省的goldfish内核配置是不支持的。

2 需要对android的bionic的线程库进行扩展,扩展方法是采用上述软件的pthread文件替换相应线程库文件。

二 编译blcr的内核驱动模块和应用 直接使用android内建的编译器即可对内核驱动进行编译。编译过程只要指定正确的编译器路径和内核路径即可顺利编译。生成的内核可加载模块分别是:

cr_module/kbuild/blcr.ko

blcr_imports/kbuild/blcr_imports.ko

顺利编译blcr应用部分需要使用打过扩展补丁的pthread。补丁方法为直接取代bionic目录下对应文件,并且修改bionic/libc/Android.mk,开启对应的编译开关,在libc_common_cflags加入-DUCLIBC_LINUXTHREAD_OLD_EXTENSTION 宏。

Blcr文件也需要如下修改才能正常编译和运行。

其中文件libcr\cr_libinit.c :

rc = __cri_ksigaction(signum, (act ? &ksa : NULL), (oact ? &oksa : NULL), (_NSIG/8), &errno);改动为:

rc = __cri_ksigaction(signum, (act ? &ksa : NULL), (oact ? &oksa : NULL), (_NSIG/4), &errno);

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwszyg.html