深入理解Zygote

1 . zygote进程是什么?

    zygote 进程是Android系统的一个主要特征, 它通过COW 方式运行在内存中的进程实现最大程度的复用, 并通过库共享有效降低内存的使用量(foot print).


2. zygote 进程的创建过程

      (1) 如何传递参数?

       service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server

      -Xzygote  : 传递给虚拟机的选项。在dalvik/vm/Init.cpp  

        } else if (strcmp(argv[i], "-Xzygote") == 0) {
1046           <strong> gDvm.zygote = true;</strong>

     --zygote: 表示要加载 com.android.internal.os.ZygoteInit 类

     --start-system-server: 传递给生成的类,用于启动系统服务器。


     (2) 在启用虚拟机时,会创建一些虚拟机选项。

     

int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)

     其中有一个,JNI check的选项。  这是通过系统属性控制的。     
    property_get("dalvik.vm.checkjni", propBuf, "");
    if (strcmp(propBuf, "true") == 0) {
        checkJni = true;
    } else if (strcmp(propBuf, "false") != 0) {
        /* property is neither true nor false; fall back on kernel parameter */
        property_get("ro.kernel.android.checkjni", propBuf, "");
        if (propBuf[0] == '1') {
            checkJni = true;
        }
    }

    设置虚拟机的heapsize,

    

    /*
     * The default starting and maximum size of the heap.  Larger
     * values should be specified in a product property override.
     */
    strcpy(heapstartsizeOptsBuf, "-Xms");
    property_get("dalvik.vm.heapstartsize", heapstartsizeOptsBuf+4, "4m");
    opt.optionString = heapstartsizeOptsBuf;
    mOptions.add(opt);
    strcpy(heapsizeOptsBuf, "-Xmx");
    property_get("dalvik.vm.heapsize", heapsizeOptsBuf+4, "16m");
    opt.optionString = heapsizeOptsBuf;
    mOptions.add(opt);

    关于JNI check中的资源检查, 系统创建的 JNI global references 个数不超过 2000

   

    ALOGD("CheckJNI is %s\n", checkJni ? "ON" : "OFF");
    if (checkJni) {
        /* extended JNI checking */
        opt.optionString = "-Xcheck:jni";
        mOptions.add(opt);

        /* set a cap on JNI global references */
        opt.optionString = "-Xjnigreflimit:2000";
        mOptions.add(opt);

        /* with -Xcheck:jni, this provides a JNI function call trace */
        //opt.optionString = "-verbose:jni";
        //mOptions.add(opt);
    }

     创建虚拟机, pEnv返回当前线程的 JNIEnv 变量。

    

    if (<strong>JNI_CreateJavaVM</strong>(pJavaVM, pEnv, &initArgs) < 0) {
        ALOGE("JNI_CreateJavaVM failed\n");
        goto bail;
    }
   

 2. 创建 system_server进程:

    有一个疑问, 多个参数是如何传递的呢? 在zygote.java   

    public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
            int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
        preFork();
        int pid = nativeForkSystemServer(
                uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
        postFork();
        return pid;
    }

    native public static int nativeForkSystemServer(int uid, int gid, int[] gids, int debugFlags,
            int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);


在 JNI层:   

/*
 * native public static int nativeForkSystemServer(int uid, int gid,
 *     int[] gids, int debugFlags, int[][] rlimits,
 *     long permittedCapabilities, long effectiveCapabilities);
 */
static void Dalvik_dalvik_system_Zygote_forkSystemServer(
        <strong>const u4* args</strong>, JValue* pResult)
{
    pid_t pid;
    pid = forkAndSpecializeCommon(args, true);

     zygote进程会check system_server进程是否创建成功,WNOHANG option使得 如果没有system_server进程退出,那么waitepid会立即返回;

  

static void Dalvik_dalvik_system_Zygote_forkSystemServer(
        const u4* args, JValue* pResult)
{
    pid_t pid;
    pid = forkAndSpecializeCommon(args, true);

    /* The zygote process checks whether the child process has died or not. */
    if (pid > 0) {
        int status;

        ALOGI("System server process %d has been created", pid);
        gDvm.systemServerPid = pid;
        /* There is a slight window that the system server process has crashed
         * but it went unnoticed because we haven't published its pid yet. So
         * we recheck here just to make sure that all is well.
         */
        if (waitpid(pid, &status, <strong>WNOHANG)</strong> == pid) {
            ALOGE("System server process %d has died. Restarting Zygote!", pid);
            kill(getpid(), SIGKILL); //自杀
        }
    }
    RETURN_INT(pid);
}

    创建system_server和 zygote的子进程用的是下面:


* Utility routine to fork zygote and specialize the child process.

static int setSELinuxContext(uid_t uid, bool isSystemServer,
                             const char *seInfo, const char *niceName)
{
#ifdef HAVE_ANDROID_OS
    return selinux_android_setcontext(uid, isSystemServer, seInfo, niceName);
#else
    return 0;
#endif
}
#endif

/*
 * Utility routine to fork zygote and specialize the child process.
 */
static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer)
{
    pid_t pid;

    uid_t uid = (uid_t) args[0];
    gid_t gid = (gid_t) args[1];
    ArrayObject* gids = (ArrayObject *)args[2];
    u4 debugFlags = args[3];
    ArrayObject *rlimits = (ArrayObject *)args[4];
    u4 mountMode = MOUNT_EXTERNAL_NONE;
    int64_t permittedCapabilities, effectiveCapabilities;
#ifdef HAVE_SELINUX
    char *seInfo = NULL;
    char *niceName = NULL;
#endif

    if (isSystemServer) {
        /*
         * Don't use GET_ARG_LONG here for now.  gcc is generating code
         * that uses register d8 as a temporary, and that's coming out
         * scrambled in the child process.  b/3138621
         */
        //permittedCapabilities = GET_ARG_LONG(args, 5);
        //effectiveCapabilities = GET_ARG_LONG(args, 7);
        permittedCapabilities = args[5] | (int64_t) args[6] << 32;
        effectiveCapabilities = args[7] | (int64_t) args[8] << 32;
    } else {
        mountMode = args[5];
        permittedCapabilities = effectiveCapabilities = 0;
#ifdef HAVE_SELINUX
        StringObject* seInfoObj = (StringObject*)args[6];
        if (seInfoObj) {
            seInfo = dvmCreateCstrFromString(seInfoObj);
            if (!seInfo) {
                ALOGE("seInfo dvmCreateCstrFromString failed");
                dvmAbort();
            }
        }
        StringObject* niceNameObj = (StringObject*)args[7];
        if (niceNameObj) {
            niceName = dvmCreateCstrFromString(niceNameObj);
            if (!niceName) {
                ALOGE("niceName dvmCreateCstrFromString failed");
                dvmAbort();
            }
        }
#endif
    }

    if (!gDvm.zygote) {
        dvmThrowIllegalStateException(
            "VM instance not started with -Xzygote");

        return -1;
    }

    if (!dvmGcPreZygoteFork()) {
        ALOGE("pre-fork heap failed");
        dvmAbort();
    }

    <strong>setSignalHandler();</strong>
    ... ...
}

     自进程创建成功后,那么在system_server中,都做了些什么操作的呢?

    

    /**
     * Finish remaining work for the newly forked system server process.
     */
    private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws ZygoteInit.MethodAndArgsCaller {

        closeServerSocket();

        // set umask to 0077 so new files and directories will default to owner-only permissions.
        Libcore.os.umask(S_IRWXG | S_IRWXO);

        if (parsedArgs.niceName != null) {
            Process.setArgV0(parsedArgs.niceName);
        }

        if (parsedArgs.invokeWith != null) {
            WrapperInit.execApplication(parsedArgs.invokeWith,
                    parsedArgs.niceName, parsedArgs.targetSdkVersion,
                    null, parsedArgs.remainingArgs);
        } else {
            /*
             * Pass the remaining arguments to SystemServer.
             */
            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);
        }

        /* should never reach here */
    }

      在上面的实现中,首先要分析的是:


        // set umask to 0077 so new files and directories will default to owner-only permissions.
       <strong> Libcore.os.umask(S_IRWXG | S_IRWXO);</strong>

           关于 package libcore.io;

           

package libcore.io;

public final class Libcore {
    private Libcore() { }

    <strong>public static Os os = new BlockGuardOs(new Posix());</strong>
}

     在java 中,可以对成员变量直接初始化。 这一点与c++ 不同。


    会调用 Posix.java , 通过jni 调用

     Posix 实现了OS接口:

   

public final class Posix implements Os {
    Posix() { }

在其实现中:
 
public native int umask(int mask);

  

你可能感兴趣的:(深入理解Zygote)