美文网首页
Android系统启动(三)-Zygote篇

Android系统启动(三)-Zygote篇

作者: Stan_Z | 来源:发表于2018-11-05 23:25 被阅读52次

    在Android系统中,Zygote是java进程的鼻祖。它在启动时会创建虚拟机,并通过fork(复制进程)的形式来创建应用程序进程和SystemServer进程。

    一、Zygote启动流程

    从上篇文章得知init启动Zygote时主要是调用app_main.cpp的main函数中的AppRuntime的start来启动zygote进程的,我们就从app_main.cpp的main函数开始分析。

    1.1 AndroidRuntime.cpp

    AppRuntime声明在app_main.cpp中,它继承AndroidRuntime,也就是我们调用start其实是调用AndroidRuntime的start函数。
    frameworks/base/core/jni/AndroidRuntime.cpp start( )方法中主要工作:

    • 调用startVm函数来创建JavaVm(DVM),并通过调用startReg函数用来为DVM注册JNI
         startVm(&mJavaVM, &env, zygote)
        
         startReg(env)
    
    • 找到ZygoteInit的main函数,并通过JNI调用,自此Zygote便进入了Java框架层。
         jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
         "([Ljava/lang/String;)V”);
    
         env->CallStaticVoidMethod(startClass, startMeth, strArray);
    
    1.2 ZygoteInit.java

    frameworks/base/core/java/com/android/internal/os/ZygoteInit.java main( )方法中主要工作:

    • 注册Zygote用的Socket,当Zygote进程将SystemServer进程启动后,就会在这个服务端的Socket上来等待ActivityManagerService请求Zygote进程来创建新的应用程序进程。

         registerZygoteSocket(socketName);
      
    • 预加载的资源、类、虚拟机实例等。

        preload();
      
    • 启动SystemServer进程,该进程承载着framework的核心服务。

         startSystemServer(abiList, socketName);
      
    • 循环等待并处理AMS发送来的创建新应用进程请求。如果收到创建应用程序的请求,则调用ZygoteConnection的runOnce函数来创建一个新的应用程序进程。

        runSelectLoop(abiList);
      

    整体流程时序图如下:

    from gityuan

    Zygote进程启动总结:
    1. 解析init.zygote.rc中的参数,创建AppRuntime并调用AppRuntime.start()方法,实际调用AndroidRuntime.start(), 通过startVM()方法创建虚拟机,再调用startReg()注册JNI函数;
    2. 通过JNI方式调用ZygoteInit.main(),第一次进入Java世界;
    3. registerZygoteSocket()建立socket通道,zygote作为通信的服务端,用于响应客户端请求;
    4. preload()预加载通用类、drawable和color资源、openGL以及共享库以及WebView,用于提高app启动效率;
    5. zygote完毕大部分工作,接下来再通过startSystemServer(),fork得力帮手system_server进程,也是上层framework的运行载体。
    6. zygote功成身退,调用runSelectLoop(),随时待命,当接收到请求创建新进程请求时立即唤醒并执行相应工作。
    7. 同时会因为surfaceflinger、servicemanager、system_server进程被杀而被动触发Zygote重启。
    8. 对于Android 5.0以上系统,有两个zygote进程,分别是zygote、zygote64两个进程,从名字可以看出分别对应32位和64位,但是确实是都创建了。
      mido:/ # ps | grep zygote
       root      714   1     2176388 47548 poll_sched 7faf1bd660 S zygote64 
       root      715   1     1613320 35496 poll_sched 00f292e3f4 S zygote
      

    二、copy-on-write fork了解一下

    linux为了提高 fork 的效率,采用了 copy-on-write 技术,从父进程fork一个子进程,刚fork之后,这两个虚拟地址实际上指向的是相同的物理地址(内存页),且把父子共享的页面标记为“只读”,但如果其中任何一个进程要对共享的页面“写操作”,这时内核会复制一个物理页面给这个进程使用,同时修改页表,把原来的只读页面标记为“可写”,留给另外一个进程使用。此时两个虚拟地址指向不同的物理地址(新的物理地址的内容从原物理地址中复制得到)。

    以Zygote进程fork应用程序进程为例:

    from gityuan

    Zygote进程地址空间中包含有预加载资源、预加载类、虚拟机实例等。当Zygote fork一个应用程序进程时,父子进程先是共享相同物理地址资源,但是仅仅只能读不能写,如果此时应用进程开始写操作,那么会从Zygote原物理地址中复制内容到一块新的物理地址上,供应用程序进程使用。这样子进程可以高效而完整地继承父进程内存地址中的数据。

    相关文章

      网友评论

          本文标题:Android系统启动(三)-Zygote篇

          本文链接:https://www.haomeiwen.com/subject/zuzexqtx.html