public class ZygoteInit {
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);
}
final Runnable caller;
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";
TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,
Trace.TRACE_TAG_DALVIK);
bootTimingsTraceLog.traceBegin("ZygoteInit");
RuntimeInit.enableDdms();
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.registerServerSocketFromEnv(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();
}
// 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, 0);
Zygote.nativeSecurityInit();
// Zygote process unmounts root storage spaces.
Zygote.nativeUnmountStorageOnInit();
ZygoteHooks.stopZygoteNoThreadCreation();
if (startSystemServer) {
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.
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
zygoteServer.closeServerSocket();
}
// We're in the child process and have exited the select loop. Proceed to execute the
// command.
if (caller != null) {
caller.run();
}
}
servermanager进程是在zygote init进程之前
他们都是ini孵化出来的---------------------
Zygote启动流程就讲到这,Zygote进程共做了如下几件事:
1.创建AppRuntime并调用其start方法,启动Zygote进程。
2.通过JNI调用ZygoteInit的main函数进入Zygote的Java框架层。(ZygoteInit.java).换句换说Zygote开创了Java框架层
3.ZygoteInit这个类 ,里面有个懒加载!它还有什么用,它会加载很多很多类。preload_class..把系统公共的累加载到系统内存
4.里面有个zygotesever,是用socket,通过registerZygoteSocket创建服务端Socket,并通过runSelectLoop函数等待ActivityManagerService的请求来创建新的应用程序进程。
5.启动SystemServer进程。
看看里面的源码,调用方法
最后再来总结一下:
Zygote 进程是由 init 进程解析 init.rc 脚本创建的,其具体的执行源码是在 App_main.main 方法,
首先会创建一个虚拟机实例,然后注册 JNI 方法,最后通过 JNI 调用进入 Java 世界来到 ZygoteInit.main 方法。
在 Java 世界中我们会为 Zygote 注册 socket 用于进程间通信,预加载一些通用的类和资源,
启动 system_server 进程,循环等待孵化创建新的进程。
4步:
1.创建虚拟机
2.预加载资源
3.循环等待孵化创建新的进程
4.启动SystemServer进程。
问题:为什么预加载资源?
因为其他应用都是通zygote进程创建,资源可以共享,继承父进程的资源!copyOnWrite
问题:资源加载加载了哪些资源?
android.jar。openGL等!
private static void preloadSharedLibraries() {
Log.i(TAG, "Preloading shared libraries...");
System.loadLibrary("android");
System.loadLibrary("compiler_rt");
System.loadLibrary("jnigraphics");
try {
System.loadLibrary("sfplugin_ccodec");
} catch (Error | RuntimeException e) {
// tolerate missing sfplugin_ccodec which is only present on Codec 2 devices
}
}
/**
* This call loads the graphics driver by making an OpenGL or Vulkan call. If the driver is
* not currently in memory it will load and initialize it. The OpenGL call itself is relatively
* cheap and pure. This means that it is a low overhead on the initial call, and is safe and
* cheap to call later. Calls after the initial invocation will effectively be no-ops for the
* system.
*/
static native void nativePreloadGraphicsDriver();
private static void maybePreloadGraphicsDriver() {
if (!SystemProperties.getBoolean(PROPERTY_DISABLE_GRAPHICS_DRIVER_PRELOADING, false)) {
nativePreloadGraphicsDriver();
}
}
问题:如何优化开机启动?
资源加载方面通过多线程
问题:应用开发为什么要用多进程:
QQ音乐(9个进程),获取更多资源,进程之间相互不影响,为了有更好的体验!
可以优化启动速度:很多加载库不用一开始就加载,可以先看到页面,然后再是音乐播放
因为多个进程,application会执行多次,不同进程加载不同的内容!
优化启动速度:可以用多线程么?
问题: zygote是由什么进程创建的
init进程
问题: 为什么要设计zygote?
因为同一用它来创建进程,方便管理
为什么zygote进程通信的时候用socket,不用binder?
因为安全,binder容易被hook,还没有启动相关的东西, 第二点:为了cs架构的设计理念!
问题:zygote进程如果挂了会怎么样?
手机会重启,因为很多服务用不了
问题:zygote进程是如何从c进程转到java进程
jni, C调用java