zygote 프로세스 시작 프로세스 해독

9309 단어

zygote 프로세스


zygote 서버가 app_에서프로세스가 시작되면 가상 머신이 시작됩니다.가상 머신의 첫 번째 Java 클래스는 ZygoteInit입니다.java.
ZygoteInit의 main 방법
public static void main(String argv[]) {
    ZygoteServer zygoteServer = new ZygoteServer();

    // Zygote goes into its own process group.
    try {
        Os.setpgid(0, 0);
    } catch (ErrnoException ex) {
        throw new RuntimeException("Failed to setpgid(0,0)", ex);
    }

    final Runnable caller;
    try {
          ...
        //1  ServerSocket
        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.
        // 2  
        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();
        }

       ...
        
        if (startSystemServer) {
            //3  SystemServer 
            Runnable r = forkSystemServer(abiList, socketName, zygoteServer);

            // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
            // child (system_server) process.
            if (r != null) {
                r.run();
                return;
            }
        }

        Log.i(TAG, "Accepting command socket connections");

        // The select loop returns early in the child process after a fork and
        // loops forever in the zygote.
        // zygote , , 。 , return 。
        //4 
        caller = zygoteServer.runSelectLoop(abiList);
    } catch (Throwable ex) {
        Log.e(TAG, "System zygote died with exception", ex);
        throw ex;
    } finally {
        //5  socket 
        zygoteServer.closeServerSocket();
    }

    // We're in the child process and have exited the select loop. Proceed to execute the
    // command.
    if (caller != null) {
        caller.run();
    }
}

1 Zygote Init main 함수의 첫 번째 중요한 작업은 Socket 서버 포트 2를 시작하여 Socket을 만든 후 Framework의 대부분 분류와 자원 3을 미리 설치한 후 System Server 프로세스 앞에 3을 주석한 곳을 만들고 새로운 프로세스를 만드는 것입니다. 이 방법은 두 개의 결과를 되돌려줍니다. 하나는 r가null입니다.현재 프로세스입니다. r는null이 아닙니다.하위 프로세스입니다.r가null일 때 주석 4를 실행합니다.runSelectLoop 메서드에는 클라이언트가 메시지를 보내기를 기다리는 고정 순환이 있습니다.r가null이 아닐 때, 하위 프로세스에 있습니다. 하위 프로세스는 이 포트를 필요로 하지 않기 때문입니다.그래서 닫기
  private static Runnable forkSystemServer(String abiList, String socketName,
            ZygoteServer zygoteServer) {
       ...
        int pid;

        try {
            parsedArgs = new ZygoteConnection.Arguments(args);
            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

            /* Request to fork the system server process */
            //1  SystemServer 
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }
        
        /* For child process */
        //2 SystemServer 
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }
            //3  socket 
            zygoteServer.closeServerSocket();
            return handleSystemServerProcess(parsedArgs);
        }

        return null;
    }

주석 1, 최종적으로nativeForkSystemServer 방법을 호출하여 프로세스 주석 2pid== 0은 생성된 프로세스가 실행하는 코드입니다.handle System Server Process는 최종적으로 Runtime Init에서findStaticMain 방법을 호출합니다.이 측의run방법에서 목표를 실행하는main방법 설명3은 서버 포트를 닫습니다.zygote에서 이전 문장을 복사해서 Socket 서버를 만들었기 때문에, 이 서버는 zygote 자신을 제외하고는 다른 프로세스에 사용되지 말아야 합니다. 그렇지 않으면 시스템에서 여러 프로세스가 Socket 클라이언트의 명령을 받을 수 있습니다.

SystemServer 프로세스


System Server는 zygote가 부화한 첫 번째 프로세스입니다. Zygote Initmain 함수에서 start System Server () 를 호출하는 것을 시작으로 최종적으로native Fork System Server 방법을 호출하여 새 프로세스를 시작한 후 Socket 서버를 닫습니다.SystemServer를 실행하는 main 방법
public static void main(String[] args) {
        new SystemServer().run();
  }

private void run() {
    try {     
       ...
        // Prepare the main looper thread (this thread).
        android.os.Process.setThreadPriority(
            android.os.Process.THREAD_PRIORITY_FOREGROUND);
        android.os.Process.setCanSelfBackground(false);
        // Looper
        Looper.prepareMainLooper();
        
        // Initialize native services.
        // so 
        System.loadLibrary("android_servers");

        // Check whether we failed to shut down last time we tried.
        // This call may not return.
        performPendingShutdown();
        
        // ActivityThread,ContextImpl
        // Initialize the system context.
        createSystemContext();

        // Create the system service manager.
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        // Prepare the thread pool for init tasks that can be parallelized
        // , 
        SystemServerInitThreadPool.get();
    } finally {
        traceEnd();  // InitBeforeStartServices
    }

    // Start services.
    try {
        traceBeginAndSlog("StartServices");
        // , , ,PMS 
        startBootstrapServices();
        // ,
        startCoreServices();
        // 
        startOtherServices();
        SystemServerInitThreadPool.shutdown();
    } catch (Throwable ex) {
        Slog.e("System", "******************************************");
        Slog.e("System", "************ Failure starting system services", ex);
        throw ex;
    } finally {
        traceEnd();
    }

    ...

    // Loop forever.
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

시작 서비스의 대부분은 System Service Manager의 start Service 방법으로 호출됩니다
  public void startService(@NonNull final SystemService service) {
    // Register it.
    mServices.add(service);
    // Start it.
    long time = SystemClock.elapsedRealtime();
    try {
        //  service  onStart 
        service.onStart();
    } catch (RuntimeException ex) {
        throw new RuntimeException("Failed to start service " + service.getClass().getName()
                + ": onStart threw an exception", ex);
    }
    warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
    }

mian을 직접 실행하는 방법도 있습니다. 예를 들어 다음과 같은 서비스 관리자가 실행됩니다.addService(xxx,m), 서비스를 캐시합니다.
    mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
            mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);

    public static PackageManagerService main(Context context, Installer installer,
        boolean factoryTest, boolean onlyCore) {
    // Self-check for initial settings.
    PackageManagerServiceCompilerMapping.checkProperties();

    PackageManagerService m = new PackageManagerService(context, installer,
            factoryTest, onlyCore);
    m.enableSystemUserPackages();
    ServiceManager.addService("package", m);
    final PackageManagerNative pmn = m.new PackageManagerNative();
    ServiceManager.addService("package_native", pmn);
    return m;
}

Service Manager는addService 방법에 추가된 것은name이 IBinder에 대한 참조입니다.이 서비스들은 모두 다른 프로세스에 제공할 수 있기 때문이다.그래서 당연히 아이비입니다.
/**
 * Place a new @a service called @a name into the service
 * manager.
 * 
 * @param name the name of the new service
 * @param service the service object
 */
public static void addService(String name, IBinder service) {
    try {
        getIServiceManager().addService(name, service, false);
    } catch (RemoteException e) {
        Log.e(TAG, "error in addService", e);
    }
}

Package Manager Service의 구조 방법을 보면 Service Thread 라인을 초기화합니다.다른 서비스도 라인이 있을 거예요.
public PackageManagerService(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
        ...
        synchronized (mInstallLock) {
        // writer
        synchronized (mPackages) {
            // 。 PackageManagerService 
            mHandlerThread = new ServiceThread(TAG,
                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
            mHandlerThread.start();
            mHandler = new PackageHandler(mHandlerThread.getLooper());
}

APK 응용 프로그램에서 직접 상호작용을 할 수 있는 대부분의 시스템 서비스는 시스템 서버 프로세스에서 실행된다. 예를 들어 Windows 관리자 서버, Activity 관리자 시스템 서비스, Package 관리자 서버 등 흔히 볼 수 있는 서비스인데 이런 시스템 서비스는 모두 하나의 라인으로 시스템 서버 프로세스에 존재한다.

좋은 웹페이지 즐겨찾기