由app_main.cpp文件中调用ZygoteInit.java 进行创建第一个虚拟机。
init.rc中可以设置与其相关的参数:
- service zygote /system/bin/app_process -Xzygote 告诉操作系统 Zygote加入到系统服务中
-Xzygote,该参数将作为虚拟机启动时所需要的参数,是在AndroidRuntime.cpp类的startVm()函数中调用JNI_CreateJavaVM()时被使用的 - /system/bin --zygote --start-system-server --开头的都是参数 比如--start-system-server指的是Zygote进程复制产生的第一个虚拟机实例是系统服务进程
- socket zygote stream 666 指定该服务所使用到的socket,后面的参数依次是名称、类型、端口地址 当用户启动一个新的应用时会通过socket告知Zygote,让她孵化出一个新的虚拟机实例
- onrestart write /sys/android_power/request_state wake 重启的条件 一般都是发生异常
- onrestart write /sys/power/state on
- onrestart restart media
- onrestart restart netd
- public static void main(String argv[]) { 这是ZygoteInit.java的main函数 从AndroidRuntime::start()进入此函数
- try {
- // Start profiling the zygote initialization.
- SamplingProfilerIntegration.start();
- registerZygoteSocket(); 启动Socket服务端口 用于监听
- EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
- SystemClock.uptimeMillis());
- preload(); 加载Framework大部分类和资源
- EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
- SystemClock.uptimeMillis());
- // Finish profiling the zygote initialization.
- SamplingProfilerIntegration.writeZygoteSnapshot();
- // Do an initial gc to clean up after startup
- gc();
- // If requested, start system server directly from Zygote
- if (argv.length != 2) {
- throw new RuntimeException(argv[0] + USAGE_STRING);
- }
- if (argv[1].equals("start-system-server")) { 检查参数是否对
- startSystemServer();
- } else if (!argv[1].equals("")) {
- throw new RuntimeException(argv[0] + USAGE_STRING);
- }
- Log.i(TAG, "Accepting command socket connections");
- if (ZYGOTE_FORK_MODE) { 复制孵化出一个虚拟机 产生一个新的进程 共享Framework的类和资源 (复制要比创建速度快)
- runForkMode();
- } else {
- runSelectLoopMode();
- }
- closeServerSocket();
- } catch (MethodAndArgsCaller caller) {
- caller.run();
- } catch (RuntimeException ex) {
- Log.e(TAG, "Zygote died with exception", ex);
- closeServerSocket();
- throw ex;
- }
关于进程的创建大概分三部分
1.内核创建一个进程数据结构,用于表示将要启动的进程
2.内核调用程序装载器函数,从指定的程序文件读取程序代码,并将这些程序代码装载到预先设定的内存地址
3.装载完毕后,内核将程序指针指向到目标程序地址的入口处开始执行指定的进程
那为什么dalvik中要使用复制而不是创建呢? 只有两个进程中共享了大量的程序。Zygote函数只是个框架,并没有执行实际的程序,把这个框架复制给其他的应用程序,只需要把实际的内容填充到框架中。大概是这个意思吧。
由于folk()函数是Linux的系统调用,Android中的Java层仅仅是对该调用进行了JNI封装而已,folk()函数是c实现的。