Android 虚拟机的进程管理

Android 虚拟机的进程管理
Android 虚拟机进程管理是依赖linux的进程体系结构的,要为应用程序创建一个进程,它会使用linux的fork机制来复制一个进程(复制进程比创建进程更高效) 。执行这个操作的就是zygote。
zygote是一个虚拟机进程,也是一个虚拟机实例的孵化器。当一个应用程序启动时,会通过socket发出请求,zygote在收到请求后会fork一个新的应用程序进程。
这么做的优点:
1)zygote进程是系统启动时创建的,他会完成虚拟机的初始化、库的加载、预制类库的加载和初始化等操作。
2)当系统需要一个新的虚拟机实例时,zygote通过复制自身,最快速的提供一个进程。
3)对于只读的系统库,所有虚拟机实例都和zygote共享一块内存区域,节省了内存开销。
4)调用fork()函数生成一个子进程时,内核并没有马上为这个子进程分配物理内存,而是先共享父进程的资源,如果子进程对先有资源不满足了,要做自己的修改,比如去执行exec,这时COW技术就起作用了,COW就是多个对象在起始时是共享某些资源的,直到某个对象需要修改该资源时才拥有自己的一份拷贝。所以,这个fork的过程就非常快了。

1.1 Zygote
Android中,所有的应用程序进程及系统服务进程(SystemServer)都是有Zygote进程孕育出来的。当AMS启动一个应用程序时,会通过SocketZygote进程通信,请求Zygote孕育出一个子进程作为即将要启动的应用程序的进程。
Andorid是基于Linux内核的,在Linux中,所有的进程都是init进程直接或间接孕育出来的。Zygote进程也是,它是在系统启动的过程中,通过解析init.rc脚本来启动的。
Zygote的启动相关的.rc文件会32位、64位。


init.zygote32.rc
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    class main
    socket zygote stream 660 root system
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart audioserver
    onrestart restart cameraserver
    onrestart restart media
    onrestart restart netd
    writepid /dev/cpuset/foreground/tasks

启动后看到的进程名是Zygote,其最初的名字是app_process

1)app_process的主函数main,
frameworks/base/cmds/app_process
int main(int argc, char* const argv[])@app_main.cpp{
	AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));

    while (i < argc) {
        const char* arg = argv[i++];
        if (strcmp(arg, "--zygote") == 0) {
            zygote = true;
            niceName = ZYGOTE_NICE_NAME;
        } else if (strcmp(arg, "--start-system-server") == 0) {
            startSystemServer = true;
        } else if (strcmp(arg, "--application") == 0) {
            application = true;
        } else if (strncmp(arg, "--nice-name=", 12) == 0) {
            niceName.setTo(arg + 12);
        } else if (strncmp(arg, "--", 2) != 0) {
            className.setTo(arg);
            break;
        } else {
            --i;
            break;
        }
    }

    if (zygote) {
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    } 
}

这个函数的主要作用是创建一个AppRuntime变量,然后调用他的start方法。AppRuntime类也定义在app_main.cpp中,

app_main.cpp
class AppRuntime : public AndroidRuntime{
public:
    AppRuntime(char* argBlockStart, const size_t argBlockLength)
        : AndroidRuntime(argBlockStart, argBlockLength)
        , mClass(NULL)
    {
    }
}

AppRuntime继承自AndroidRuntimeframeworks/base/core/jni)。

AndroidRuntime.cpp
AndroidRuntime::AndroidRuntime(char* argBlockStart, const size_t argBlockLength) :
        mExitWithoutCleanup(false),
        mArgBlockStart(argBlockStart),
        mArgBlockLength(argBlockLength)
{
    SkGraphics::Init();
    // Pre-allocate enough space to hold a fair number of options.
    mOptions.setCapacity(20);
    assert(gCurRuntime == NULL);        // one per process
    gCurRuntime = this;
}

当创建AppRuntime对象时,会调用父类AndroidRuntime的构造函数,在AndroidRuntime的构造函数里,会将this指针保存到静态全局变量gCurRuntime中,这样其他地方需要使用这个AppRuntime对象时,可以通过下面的函数获取这个对象的指针。

AndroidRuntime* AndroidRuntime::getRuntime()
{
    return gCurRuntime;
}

接着看app_main.cpp的的main()函数,根据init.rc中的启动参数:--zygote--start-system-server,最终会执行的语句是:

runtime.start("com.android.internal.os.ZygoteInit",args, zygote);

直接调用父类的start函数。

2)AndroidRuntime.start
AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool 	zygote)@AndroidRuntime.cpp{
	 static const String8 startSystemServer("start-system-server");
    
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
   
    JNIEnv* env;
    if (startVm(&mJavaVM, &env, zygote) != 0) {
        return;
    }

    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }

    char* slashClassName = toSlashClassName(className);
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        /* keep going */
    } else {
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
            ALOGE("JavaVM unable to find main() in '%s'\n", className);
            /* keep going */
        } else {
            env->CallStaticVoidMethod(startClass, startMeth, strArray);
        }
    }
}

这个函数的主要作用是启动Android系统运行时库,主要做了三件事情,一是调用函数startVM启动虚拟机,二是调用函数startReg注册jni方法,三是最后那段代码块,调用com.android.internal.os.ZygoteInit类的main函数。


在StartVm前,调用了JniInvocation的init函数,这个函数在libnativehelper/JniInvocation.cpp中

bool JniInvocation::Init(const char* library) {
#ifdef __ANDROID__
  char buffer[PROP_VALUE_MAX];
#else
  char* buffer = NULL;
#endif
  library = GetLibrary(library, buffer);
  // Load with RTLD_NODELETE in order to ensure that libart.so is not unmapped when it is closed.
  // This is due to the fact that it is possible that some threads might have yet to finish
  // exiting even after JNI_DeleteJavaVM returns, which can lead to segfaults if the library is
  // unloaded.
  const int kDlopenFlags = RTLD_NOW | RTLD_NODELETE;
  handle_ = dlopen(library, kDlopenFlags);
  if (handle_ == NULL) {
    if (strcmp(library, kLibraryFallback) == 0) {
      // Nothing else to try.
      ALOGE("Failed to dlopen %s: %s", library, dlerror());
      return false;
    }
    // Note that this is enough to get something like the zygote
    // running, we can't property_set here to fix this for the future
    // because we are root and not the system user. See
    // RuntimeInit.commonInit for where we fix up the property to
    // avoid future fallbacks. http://b/11463182
    ALOGW("Falling back from %s to %s after dlopen error: %s",
          library, kLibraryFallback, dlerror());
    library = kLibraryFallback;
    handle_ = dlopen(library, kDlopenFlags);
    if (handle_ == NULL) {
      ALOGE("Failed to dlopen %s: %s", library, dlerror());
      return false;
    }
  }
  if (!FindSymbol(reinterpret_cast<void**>(&JNI_GetDefaultJavaVMInitArgs_),
                  "JNI_GetDefaultJavaVMInitArgs")) {
    return false;
  }
  if (!FindSymbol(reinterpret_cast<void**>(&JNI_CreateJavaVM_),
                  "JNI_CreateJavaVM")) {
    return false;
  }
  if (!FindSymbol(reinterpret_cast<void**>(&JNI_GetCreatedJavaVMs_),
                  "JNI_GetCreatedJavaVMs")) {
    return false;
  }
  return true;
}
通过其中的GetLibrary(null,,,)函数,因为参数为null,获取默认的default_library为libart.so,接着是dlopen打开这个libart.so文件,调用FindSymbol函数从

libart.so中搜索符号JNI_CreateJavaVM,对应文件ar/runtime/java_vm_ext.cc中的JNI_CreateJavaVM函数。这个不同的库文件对应不同的文件,如果是dalvik虚拟机,对应libdvm.so,相应的符号JNI_CreateJavaVM对应就是dalvikvm中的文件函数。


在调用AndroidRuntime::startVm()启动虚拟机时,函数的最后就是调用JNI_CreateJavaVM函数。

int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote){
    /*
     * Initialize the VM.
     *
     * The JavaVM* is essentially per-process, and the JNIEnv* is per-thread.
     * If this call succeeds, the VM is ready, and we can start issuing
     * JNI calls.
     */
    if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
        ALOGE("JNI_CreateJavaVM failed\n");
        return -1;
    }
}
接着看art/runtime/Java_vm_ext.cc文件中的JNI_CreateJavaVM函数


extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {
  ScopedTrace trace(__FUNCTION__);
  const JavaVMInitArgs* args = static_cast<JavaVMInitArgs*>(vm_args);
  if (IsBadJniVersion(args->version)) {
    LOG(ERROR) << "Bad JNI version passed to CreateJavaVM: " << args->version;
    return JNI_EVERSION;
  }
  RuntimeOptions options;
 //解析虚拟机参数存到javaVMOption中。
  for (int i = 0; i < args->nOptions; ++i) {
    JavaVMOption* option = &args->options[i];
    options.push_back(std::make_pair(std::string(option->optionString), option->extraInfo));
  }
  bool ignore_unrecognized = args->ignoreUnrecognized;
//调用create函数,创建Runtime实例。
 if (!Runtime::Create(options, ignore_unrecognized)) {
    return JNI_ERR;
  }

  // Initialize native loader. This step makes sure we have
  // everything set up before we start using JNI.
  android::InitializeNativeLoader();

//获取runtime实例,然后调用其start方法。
  Runtime* runtime = Runtime::Current();
  bool started = runtime->Start();
  if (!started) {
    delete Thread::Current()->GetJniEnv();
    delete runtime->GetJavaVM();
    LOG(WARNING) << "CreateJavaVM failed";
    return JNI_ERR;
  }

  *p_env = Thread::Current()->GetJniEnv();
  *p_vm = runtime->GetJavaVM();
  return JNI_OK;
}
   调用art/runtime/Runtime.cc中的create函数,创建 Runtime实例,然后初始化runtime。

bool Runtime::Create(RuntimeArgumentMap&& runtime_options) {
  // TODO: acquire a static mutex on Runtime to avoid racing.
  if (Runtime::instance_ != nullptr) {
    return false;
  }
  instance_ = new Runtime;
  if (!instance_->Init(std::move(runtime_options))) {
    // TODO: Currently deleting the instance will abort the runtime on destruction. Now This will
    // leak memory, instead. Fix the destructor. b/19100793.
    // delete instance_;
    instance_ = nullptr;
    return false;
  }
  return true;
调用的art/runtime/Runtime.cc中的start函数。
bool Runtime::Start() {
  VLOG(startup) << "Runtime::Start entering";

  CHECK(!no_sig_chain_) << "A started runtime should have sig chain enabled";

  // If a debug host build, disable ptrace restriction for debugging and test timeout thread dump.
  // Only 64-bit as prctl() may fail in 32 bit userspace on a 64-bit kernel.
#if defined(__linux__) && !defined(__ANDROID__) && defined(__x86_64__)
  if (kIsDebugBuild) {
    CHECK_EQ(prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY), 0);
  }
#endif

  // Restore main thread state to kNative as expected by native code.
  Thread* self = Thread::Current();

  self->TransitionFromRunnableToSuspended(kNative);

  started_ = true;

  // Create the JIT either if we have to use JIT compilation or save profiling info.
  // TODO(calin): We use the JIT class as a proxy for JIT compilation and for
  // recoding profiles. Maybe we should consider changing the name to be more clear it's
  // not only about compiling. b/28295073.
  if (jit_options_->UseJitCompilation() || jit_options_->GetSaveProfilingInfo()) {
    std::string error_msg;
    if (!IsZygote()) {
    // If we are the zygote then we need to wait until after forking to create the code cache
    // due to SELinux restrictions on r/w/x memory regions.
      CreateJit();
    } else if (jit_options_->UseJitCompilation()) {
      if (!jit::Jit::LoadCompilerLibrary(&error_msg)) {
        // Try to load compiler pre zygote to reduce PSS. b/27744947
        LOG(WARNING) << "Failed to load JIT compiler with error " << error_msg;
      }
    }
  }

  if (!IsImageDex2OatEnabled() || !GetHeap()->HasBootImageSpace()) {
    ScopedObjectAccess soa(self);
    StackHandleScope<2> hs(soa.Self());

    auto class_class(hs.NewHandle<mirror::Class>(mirror::Class::GetJavaLangClass()));
    auto field_class(hs.NewHandle<mirror::Class>(mirror::Field::StaticClass()));

    class_linker_->EnsureInitialized(soa.Self(), class_class, true, true);
    // Field class is needed for register_java_net_InetAddress in libcore, b/28153851.
    class_linker_->EnsureInitialized(soa.Self(), field_class, true, true);
  }

  // InitNativeMethods needs to be after started_ so that the classes
  // it touches will have methods linked to the oat file if necessary.
  {
    ScopedTrace trace2("InitNativeMethods");
    InitNativeMethods();
  }

  // Initialize well known thread group values that may be accessed threads while attaching.
  InitThreadGroups(self);

  Thread::FinishStartup();

  system_class_loader_ = CreateSystemClassLoader(this);

  if (is_zygote_) {
    if (!InitZygote()) {
      return false;
    }
  } else {
    if (is_native_bridge_loaded_) {
      PreInitializeNativeBridge(".");
    }
    NativeBridgeAction action = force_native_bridge_
        ? NativeBridgeAction::kInitialize
        : NativeBridgeAction::kUnload;
    InitNonZygoteOrPostFork(self->GetJniEnv(),
                            /* is_system_server */ false,
                            action,
                            GetInstructionSetString(kRuntimeISA));
  }

  StartDaemonThreads();

  {
    ScopedObjectAccess soa(self);
    self->GetJniEnv()->locals.AssertEmpty();
  }

  VLOG(startup) << "Runtime::Start exiting";
  finished_starting_ = true;

  if (profiler_options_.IsEnabled() && !profile_output_filename_.empty()) {
    // User has asked for a profile using -Xenable-profiler.
    // Create the profile file if it doesn't exist.
    int fd = open(profile_output_filename_.c_str(), O_RDWR|O_CREAT|O_EXCL, 0660);
    if (fd >= 0) {
      close(fd);
    } else if (errno != EEXIST) {
      LOG(WARNING) << "Failed to access the profile file. Profiler disabled.";
    }
  }

  if (trace_config_.get() != nullptr && trace_config_->trace_file != "") {
    ScopedThreadStateChange tsc(self, kWaitingForMethodTracingStart);
    Trace::Start(trace_config_->trace_file.c_str(),
                 -1,
                 static_cast<int>(trace_config_->trace_file_size),
                 0,
                 trace_config_->trace_output_mode,
                 trace_config_->trace_mode,
                 0);
  }

  return true;
}

通过Thread::Current();获取当前的运行线程,然后将线程挂起,初始化本地函数InitNativeMethods();等等。。。


3)ZygoteInit.java (frameworks/base/core/java/com/android/internal/os)
ZygoteInit.java
public static void main(String argv[]) @ZygoteInit.java{
	registerZygoteSocket(socketName);
	preload();
	startSystemServer(abiList, socketName);
	runSelectLoop(abiList);
}

这个函数主要做了三件事情,一是调用registerZygoteSocket函数创建了一个socket接口,用来跟系统服务通信,二是调用startSystemServer函数启动SystemServer进程,三是调用runSelectLoop函数进入一个无限循环,在socket接口上等待系统服务创建应用程序进程的请求。

4) registerZygoteSocket函数
private static final String ANDROID_SOCKET_PREFIX = "ANDROID_SOCKET_";
private static void registerZygoteSocket(String socketName)@ZygoteInit.java {
	final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
	String env = System.getenv(fullSocketName);
	fileDesc = Integer.parseInt(env);

	FileDescriptor fd = new FileDescriptor();
	fd.setInt$(fileDesc);
	sServerSocket = new LocalServerSocket(fd);
}

这接口的socket是通过文件描述符创建的,这个文件描述符就是/dev/socket/zygote文件,可以通过环境变量ANDROID_SOCKET_PREFIX +socketName来得到。那么这个环境的值又是谁来设置的?系统启动的init.rc脚本是由init.cpp文件来解析的,具体到service命令是由Service.cpp来解析的,

system/core/init/Service.cpp

bool Service::Start() @service.cpp{
	pid_t pid = fork();
        for (const auto& si : sockets_) {
            int socket_type = ((si.type == "stream" ? SOCK_STREAM :
                                (si.type == "dgram" ? SOCK_DGRAM :
                                 SOCK_SEQPACKET)));
            const char* socketcon =
                !si.socketcon.empty() ? si.socketcon.c_str() : scon.c_str();

            int s = create_socket(si.name.c_str(), socket_type, si.perm,
                                  si.uid, si.gid, socketcon);
            if (s >= 0) {
                PublishSocket(si.name, s);
            }
        }
}

每个service命令都会让init进程调用fork函数来创建一个新的进程,在新的进程中会解析socket选项对于每个socket选项,会通过creae_socket函数在/dev/socket/目录下创建一个文件,这个场景中创建的文件是zygote,然后把得到的文件描述符通过publish_socket函数写入环境变量中。

void Service::PublishSocket(const std::string& name, int fd) const @service.cpp{
    std::string key = StringPrintf(ANDROID_SOCKET_ENV_PREFIX "%s", name.c_str());
    std::string val = StringPrintf("%d", fd);
    add_environment(key.c_str(), val.c_str());

    /* make sure we don't close-on-exec */
    fcntl(fd, F_SETFD, 0);
}

这里传进来的参数namezygote,添加前缀:

#defineANDROID_SOCKET_ENV_PREFIX "ANDROID_SOCKET_"

因此这个文件描述符相应的key值是:ANDROID_SOCKET_zygote,通过add_environment添加到环境变量中。

因为registerZygoteSocket()@ZygoteInit.java函数和create_socket函数都是运行在init进程中的,所以在registerZygoteSocket函数中可以直接使用这个文件描述符来创建一个java层的LocalServerSocket对象。

其他进程如果要打开/dec/socket/zygote文件来和zygote进程通信,就要文件名来连接这个LocalServerSocket对象,如AMS通过Process.start函数来创建一个新的进程,Process.start函数会先通过Socket连接到Zygote进程中,最终由Zygote进程来完成创建新的应用程序进程,这个过程中Process类是通过openZygoteSocketIfNeeded函数来连接到Zygote进程中的Socket

public static final String ZYGOTE_SOCKET = "zygote";
private static ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx 	@Process.java{
	primaryZygoteState = ZygoteState.connect(ZYGOTE_SOCKET);
}

这里的ZYGOTE_SOCKET对应了/dev/socket/目录下的zygote文件。

Android中的socket机制和binder机制类似,都可以用来实现进程间通信。现在回到ZygoteInit.main()函数中,接着是startSystemServer启动SystemServer进程。

5)startSystemServer
ZygoteInit.java
private static boolean startSystemServer(String abiList, String socketName)@ZygoteInit.java{
        /* Hardcoded command line to start the system server */
        String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,
		1032,3001,3002,3003,3006,3007,3009,3010",
            "--capabilities=" + capabilities + "," + capabilities,
            "--nice-name=system_server",
            "--runtime-args",
            "com.android.server.SystemServer",
        };

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

            /* Request to fork the system server process */
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);

        /* For child process */
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }

            handleSystemServerProcess(parsedArgs);
        }
}

Zygote进程通过Zygote.forkSystemServer()函数来创建新的进程,新创建的进程会执行handleSystemServerProcess函数。

6) handleSystemServerProcess
ZygoteInit.java
private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws ZygoteInit.MethodAndArgsCaller@ZygoteInit.java {
	closeServerSocket();
	RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}

这个函数的重点是调用RuntimeInit.zygoteInit函数进一步启动SystemServer组件。由于zygote进程创建的子进程会继承zygotesocket文件描述符,如果子进程不会用到,就可以调用closeServerSocket函数关闭它。


7)zygoteInit
RuntimeInit.java
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller @RuntimeInit.java{
	nativeZygoteInit();
	applicationInit(targetSdkVersion, argv, classLoader);
}

这个函数执行两个操作,一是调用nativeZygoteInit函数执行Binder进程间通信机制的初始化工作,完成后,进程间的Bidner对象就可以方便地进行进程间通信了,二是调用com.android.server.systemserver类的main函数,这个是applicationInit中执行的。

8nativeZygoteInit

这是个native函数,实现在AndroidRuntime.cpp中。

static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
@AndroidRuntime.cpp{
    gCurRuntime->onZygoteInit();
}

onZygoteInit调用的具体子类AppRuntime中的实现,

virtual void onZygoteInit()@app_main.cpp{
        sp<ProcessState> proc = ProcessState::self();
        ALOGV("App process: starting thread pool.\n");
        proc->startThreadPool();
    }

通过ProcessStateIPCThreadState完成进程间通信Binder的准备工作。

回到7)步中,接着执行com.android.server.systemserver类的main函数。

9)SystemServer.main
    public static void main(String[] args) @SystemServer.java{
        new SystemServer().run();
    }
private void run() @SystemServer.java{
	Looper.prepareMainLooper();
	startBootstrapServices();
	startCoreServices();
	startOtherServices();
	Looper.loop();
}

这里会启动一个systemserver主线程,来完成各类系统服务的启动。

各类服务启动完成后,层层返回,到3)步中ZygoteInit.main中,最后执行的是runSelectLoop进入一个无限循环,在socket上等待创建引用进程的请求。

10)runSelectLoop
private static void runSelectLoop(String abiList) throws MethodAndArgsCaller @ZygoteInit.java{
        ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();

        fds.add(sServerSocket.getFileDescriptor());
        peers.add(null);
     while (true) {
            StructPollfd[] pollFds = new StructPollfd[fds.size()];
            for (int i = 0; i < pollFds.length; ++i) {
                pollFds[i] = new StructPollfd();
                pollFds[i].fd = fds.get(i);
                pollFds[i].events = (short) POLLIN;
            }
            try {
                Os.poll(pollFds, -1);
            } catch (ErrnoException ex) {
                throw new RuntimeException("poll failed", ex);
            }
            for (int i = pollFds.length - 1; i >= 0; --i) {
                if ((pollFds[i].revents & POLLIN) == 0) {
                    continue;
                }
                if (i == 0) {
                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
                    peers.add(newPeer);
                    fds.add(newPeer.getFileDesciptor());
                } else {
                    boolean done = peers.get(i).runOnce();
                    if (done) {
                        peers.remove(i);
                        fds.remove(i);
                    }
                }
            }
        }
}

这个循环等待系统服务来连接socket,然后调用runOnce函数创建新的进程。


系统启动时,init进程会创建zygote进程,zygote进程负责后续Android应用程序框架层的其他进程的创建和启动;

zygote进程会先创建一个systemserver进程,systemserver进程负责启动启动的关键服务,如WindowManagerService,ActivityManagerService等;

当需要启动一个Android应用程序时,AMS会通过通过socket进程间通信机制,通知zygote进程为这个应用程序创建一个新的进程。


  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值