对Zygote启动流程的理解

Zygote的作用是什么?

Zygote主要作用有两点:
1.启动SystemServer。
2.孵化应用进程。
应用启动时会将常用类、JNI函数、主题资源、共享库等直接从Zygote继承,避免每个应用进程都加载一边相同的资源,达到资源共享提升性能的目的。

启动流程

进程启动

1.Linux系统启动之后,用户空间启动第一个进程init进程,init进程会读取init.rc文件,启动init.rc文件中记录的需要启动的进程。Zygote就是需要启动的进程之一。

启动配置文件init.rc部分配置:

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main 
socket zygote stream 660 root system 
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
writepid /dev/cpuset/foreground/tasks

2.进程是如何启动的?
Linux启动进程有两种方式,第一种是fork+handle,第二种是fork+execve.这里使用fork+execve启动进程。
fork+handle方式:

pid_t pid = fork();
if(pid==0){
    //child process 
}else{
    //parent process
}

fork+execve方式:

pid_t pid = fork();
if(pid==0){
    //child process 
    //@path 可执行程序的路径
    //@argv 执行程序的参数
    //@env 环境变量
    execve(path,argv,env);
}else{
    //parent process
}

fork函数会分别在父进程和子进程各返回一次,在子进程中返回的pid值为0,父进程中返回进程的pid,我们可以通过pid的值判断是在父进程还是子进程中。
默认情况下,创建的子进程会继承父进程的所以资源。如果调用了execve加载调用了另一个二进制程序,继承的父进程资源将被新启动程序的资源替换掉。
3.信号处理-SIGCHLD
父进程fork出子进程,如果子进程异常中止了,父进程就会收到一个SIGCHLD信号,重启子进程。如:init进程fork出zygote进程,如果zygote进程异常中止了,init进程会接收到SIGCHLD信号,然后重启zygote进程。

准备工作

Zygote进程启动之后做了什么?
Zygote启动之后,执行了execve系统调用,这个系统调用执行的是一个用C++编写的二进制可执行程序,做了一些准备工作后,Zygote就会切换到Java部分中运行。
-Zygote的Native部分
Zygote的Native部分主要有三个事情需要准备:
1.启动android虚拟机
2.注册Android的JNI函数
3.进入Java世界

int main(int argc,char *argv[]){
    JavaVM *jvm;
    JNIEnv *env;
    JNI_CreateJavaVM(&jvm,(void **)&env,&vm_args);
    jclass clazz = env->FindClass("ZygoteInit");
    jmethodID method = env-> GetStaticMethodId(clazz,"Main","([Ljava/lang/String;)V");
    env->CallStaticVoidMethod(clazz,method,args);
    jvm->DestroyJavaVM();
}

-Zygote的Java部分
1.Preload Resource
首先,zygote会预加载资源:常用类、JNI函数、主题资源、共享库等。
2.fork SystemServer
然后,zygote进程调用fork函数,启动SystemServer进程。
3.进入loop循环
接下来,SystemServer会使用Socket与Loop循环进行通信。

Loop循环

在Loop循环中。主要接收和处理Socket/MQ/Binder驱动等发来的消息。Loop循环是如何处理请求的?

boolean runOnce(){
    String[] args = readArgumentList();
    int pid = Zygote.forkAndSpecialize();
    if(pid==0){
        //in child process
        handleChildProc(args,...);
        return true;
    }
}

在runOnce函数中,先读取由AMS跨进程发送来的参数列表,然后根据参数fork出子进程,最后子进程中执行ActivityThread.main();函数。

注意:
1.Zygote在fork时要保证是单线程的。父进程中有多少个线程,如守护线程和多个虚拟机,子进程在创建的时候只有一个线程,对于子进程来说,为防止线程安全问题,如资源抢占导致死锁等情况,在fork时先暂停其他线程,fork进程结束后,再重启恢复其他线程。
2.Zygote的IPC没有采用Binder机制,而是采用了本地的socket。binder机制并不是从Zygote继承而来,而是应用程序启动之后,自己启动的binder机制。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352