zoukankan      html  css  js  c++  java
  • Android 源码分析(五) Zygote 进程

    一.前言:  

        init进程 –> Zygote进程 –> SystemServer进程 –> Launcher桌面程序 -> 我们的App应用

        init进程:linux的根进程,android系统是基于linux系统的,因此可以算作是整个android操作系统的第一个进程;

        Zygote进程:android系统的根进程,主要作用:可以作用Zygote进程fork出SystemServer进程和各种应用进程;

        SystemService进程:主要是在这个进程中启动系统的各项服务,比如ActivityManagerService,PackageManagerService,WindowManagerService服务等等;
        
        Launcher桌面程序:就是我们平时看到的桌面程序,它其实也是一个android应用程序,只不过这个应用程序是系统默认第一个启动的应用程序.            

    二. Zygote进程 

           Android系统是基于Linux内核的,而在Linux系统中,所有的进程都是init进程的子孙进程,也就是说,所有的进程都是直接或者间接地由init进程fork出来的。Zygote进程也不例外,它是在系统启动的过程,由init进程创建的.
           init进程在启动Zygote进程时一般都会调用ZygoteInit类的main方法.

      如果SystemServer崩溃了,Zygote也会kill自己,重新创建进程服务。

       

    //ZygoteInit.java
        public static void main(String argv[]) {
            ZygoteServer zygoteServer = new ZygoteServer();
    
            // Mark zygote start. This ensures that thread creation will throw
            // an error.
            ZygoteHooks.startZygoteNoThreadCreation();
    
            // Zygote goes into its own process group.
            try {
                Os.setpgid(0, 0);
            } catch (ErrnoException ex) {
                throw new RuntimeException("Failed to setpgid(0,0)", ex);
            }
    
            try {
                // Report Zygote start time to tron unless it is a runtime restart
                if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
                    MetricsLogger.histogram(null, "boot_zygote_init",
                            (int) SystemClock.elapsedRealtime());
                }
    
                String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
                BootTimingsTraceLog bootTimingsTraceLog = new BootTimingsTraceLog(bootTimeTag,
                        Trace.TRACE_TAG_DALVIK);
                bootTimingsTraceLog.traceBegin("ZygoteInit");
                RuntimeInit.enableDdms();
                // Start profiling the zygote initialization.
                SamplingProfilerIntegration.start();
    
                boolean startSystemServer = false;
                String socketName = "zygote";
                String abiList = null;
                boolean enableLazyPreload = false;
                for (int i = 1; i < argv.length; i++) {
                    if ("start-system-server".equals(argv[i])) {
                        startSystemServer = true;
                    } else if ("--enable-lazy-preload".equals(argv[i])) {
                        enableLazyPreload = true;
                    } else if (argv[i].startsWith(ABI_LIST_ARG)) {
                        abiList = argv[i].substring(ABI_LIST_ARG.length());
                    } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
                        socketName = argv[i].substring(SOCKET_NAME_ARG.length());
                    } else {
                        throw new RuntimeException("Unknown command line argument: " + argv[i]);
                    }
                }
    
                if (abiList == null) {
                    throw new RuntimeException("No ABI list supplied.");
                }
    
                zygoteServer.registerServerSocket(socketName);
                // In some configurations, we avoid preloading resources and classes eagerly.
                // In such cases, we will preload things prior to our first fork.
                if (!enableLazyPreload) {
                    bootTimingsTraceLog.traceBegin("ZygotePreload");
                    EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                        SystemClock.uptimeMillis());
                    preload(bootTimingsTraceLog);
                    EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                        SystemClock.uptimeMillis());
                    bootTimingsTraceLog.traceEnd(); // ZygotePreload
                } else {
                    Zygote.resetNicePriority();
                }
    
                // Finish profiling the zygote initialization.
                SamplingProfilerIntegration.writeZygoteSnapshot();
    
                // Do an initial gc to clean up after startup
                bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
                gcAndFinalize();
                bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
    
                bootTimingsTraceLog.traceEnd(); // ZygoteInit
                // Disable tracing so that forked processes do not inherit stale tracing tags from
                // Zygote.
                Trace.setTracingEnabled(false);
    
                // Zygote process unmounts root storage spaces.
                Zygote.nativeUnmountStorageOnInit();
    
                // Set seccomp policy
                Seccomp.setPolicy();
    
                ZygoteHooks.stopZygoteNoThreadCreation();
    
                if (startSystemServer) {
                    startSystemServer(abiList, socketName, zygoteServer);
                }
    
                Log.i(TAG, "Accepting command socket connections");
                zygoteServer.runSelectLoop(abiList);
    
                zygoteServer.closeServerSocket();
            } catch (Zygote.MethodAndArgsCaller caller) {
                caller.run();
            } catch (Throwable ex) {
                Log.e(TAG, "System zygote died with exception", ex);
                zygoteServer.closeServerSocket();
                throw ex;
            }
        }
        //1.registerServerSocket
        //2.调用preload加载资源,
        //3.利用gcAndFinalize初始化gc,
        //4.启动SystemServer,startSystemServer() 这里启动SystemServer服务.
        //5.调用runSelectLoop运行Zygote进程选择的looper,
        //6.关闭和清理zygote sockets 
        
    //ZygoteServer.java
        /**
         * Registers a server socket for zygote command connections
         *
         * @throws RuntimeException when open fails
         */
        void registerServerSocket(String socketName) {
            if (mServerSocket == null) {
                int fileDesc;
                final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
                try {
                    String env = System.getenv(fullSocketName);
                    fileDesc = Integer.parseInt(env);
                } catch (RuntimeException ex) {
                    throw new RuntimeException(fullSocketName + " unset or invalid", ex);
                }
    
                try {
                    FileDescriptor fd = new FileDescriptor();
                    fd.setInt$(fileDesc);
                    mServerSocket = new LocalServerSocket(fd);
                } catch (IOException ex) {
                    throw new RuntimeException(
                            "Error binding to local socket '" + fileDesc + "'", ex);
                }
            }
        }
    //ZygoteInit.java
        static void preload(BootTimingsTraceLog bootTimingsTraceLog) {
            Log.d(TAG, "begin preload");
            bootTimingsTraceLog.traceBegin("BeginIcuCachePinning");
            beginIcuCachePinning();
            bootTimingsTraceLog.traceEnd(); // BeginIcuCachePinning
            bootTimingsTraceLog.traceBegin("PreloadClasses");
            //初始化Zygote中需要的class类        
            preloadClasses();
            bootTimingsTraceLog.traceEnd(); // PreloadClasses
            bootTimingsTraceLog.traceBegin("PreloadResources");
            //初始化系统资源
            preloadResources();
            bootTimingsTraceLog.traceEnd(); // PreloadResources
            Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadOpenGL");
            //初始化OpenGL
            preloadOpenGL();
            Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
            //初始化系统libraries
            preloadSharedLibraries();
            //初始化文字资源
            preloadTextResources();
            // Ask the WebViewFactory to do any initialization that must run in the zygote process,
            // for memory sharing purposes.
            //初始化webview
            WebViewFactory.prepareWebViewInZygote();
            endIcuCachePinning();
            warmUpJcaProviders();
            Log.d(TAG, "end preload");
    
            sPreloadComplete = true;
        }
    //进去看看初始化webview方法
        //WebViewFactory.java
        /**
         * Perform any WebView loading preparations that must happen in the zygote.
         * Currently, this means allocating address space to load the real JNI library later.
         */
        public static void prepareWebViewInZygote() {
            try {
                System.loadLibrary("webviewchromium_loader");
                long addressSpaceToReserve =
                        SystemProperties.getLong(CHROMIUM_WEBVIEW_VMSIZE_SIZE_PROPERTY,
                        CHROMIUM_WEBVIEW_DEFAULT_VMSIZE_BYTES);
                sAddressSpaceReserved = nativeReserveAddressSpace(addressSpaceToReserve);
    
                if (sAddressSpaceReserved) {
                    if (DEBUG) {
                        Log.v(LOGTAG, "address space reserved: " + addressSpaceToReserve + " bytes");
                    }
                } else {
                    Log.e(LOGTAG, "reserving " + addressSpaceToReserve +
                            " bytes of address space failed");
                }
            } catch (Throwable t) {
                // Log and discard errors at this stage as we must not crash the zygote.
                Log.e(LOGTAG, "error preparing native loader", t);
            }
        }
  • 相关阅读:
    Linux .下Apache的安装
    从程序员到项目经理:项目管理三大目标
    linux下mysql安装
    Linux学习之常用命令
    转载:struts2拦截器
    el自定义函数库
    JAVA正则表达式小结
    JSP自定义标记
    JAVA动态代理(JDK和CGLIB)
    JAVA反射机制
  • 原文地址:https://www.cnblogs.com/bugzone/p/zygote.html
Copyright © 2011-2022 走看看