Zygote启动分析
基于性能的考虑,Dalvik虚拟机只启动一次,新的实例将从第一次启动的Dalvik中拷贝。这个功能是通过系统服务Zygote来实现的。
Zygote的启动过程简述如下:首先,它预初始化和预加载通用的Android类到它的堆中。然后,它监听在Socket端口上,等待启动一个新的Android应用程序的命令。当接收到一个启动应用程序命令,它将利用已经加载的应用程序fork出一个新的进程。该进程就是被启动的应用程序,且与原始的Zygote进程共享同一个写时复制(copy-on-write)映射的堆。因此,Zygote的堆被链接到该新进程。如果该应用程序只从堆中读取数据,那么就一直与Zygote共享堆。但是,一旦应用程序在堆上执行写操作,那么堆对应的内存页被会被复制且会链接到新页上。这样,应用程序就可以修改过堆中的数据而不用担心会影响Zygote进程的堆了。
当一个新的Android应用程序产生时,它使用Zygote的内存布局,因此,对每个应用程序来说,它们的内存布局是一样的。
下面分析一下代码的流程:
1. 根据init.rc的启动服务的命令,将运行/system/bin/app_process启动zygote。 app_process的命令参数形式为:app_process[java-options] cmd-dir start-class-name [options],
由此可知,传入虚拟机的参数为-Xzygote,首先,-X一般是虚拟机的非标准选项,允许虚拟机定义一些特别的选项,其中zygote就是dalvik虚拟机定义的特制的选项,表示当前运行在zygote模式。在zygote模式下,虚拟机不会启动额外的线程。命令所在的目录是/system/bin,传给app_process的参数是--zygote和--start-system-server。这两个参数表示当前启动的进程名字叫zygote,并且要启动SystemServer。
while (i < argc) { const char* arg = argv[i++]; if (!parentDir) { parentDir = arg; } else if (strcmp(arg, "--zygote") == 0) { zygote = true; niceName = "zygote"; } 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 = arg + 12; } else { className = arg; break; } } |
2. 接下来,将启动ZygoteInit这个类。在启动这个类之前,会调用startVM(JavaVM** pJavaVM, JNIEnv** pEnv)创建一个dalvik虚拟机,其中JavaVM代表dalvik虚拟机的一个实例,每个进程只有一个实例,JNIEnv代表一个dalvik虚拟机运行环境,每个线程拥有一个实例。接下来通过调用startReg(env)来向虚拟机注册一些JNI本地函数。最后进入ZygoteInit类中的入口函数main中去运行。
… if (zygote) { runtime.start("com.android.internal.os.ZygoteInit", startSystemServer ? "start-system-server" : ""); } else if (className) { … |
在Android::start()方法中,启动虚拟机以及注册Android的JNI本地函数。
void AndroidRuntime::start(const char* className, const char* options) { ... /* start the virtual machine */ JNIEnv* env; if (startVm(&mJavaVM, &env) != 0) { return; } onVmCreated(env); /* * Register android functions. */ if (startReg(env) < 0) { ALOGE("Unable to register all android natives\n"); return; } ... /* * Start VM. This thread becomes the main thread of the VM, and will * not return until the VM exits. */ 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); #if 0 if (env->ExceptionCheck()) threadExitUncaughtException(env); #endif } } ... } |
3. 接下来,将进入ZygoteInit的main方法,首先registerZygoteSocket()会注册一个服务器端的本地Socket,Socket的路径由环境变量ANDROID_SOCKET_zygote指定。它的主要目的是监听启动应用程序的命令请求,并fork一个子进程来处理启动相应的应用程序。然后,preload()函数会预加载一些资源和一些通用类(由preloaded-classes资源文件指定)。接下来,调用startSystemServer()来启动SystemServer进程。主线程继续执行代码,最后阻塞在runSelectLoop(),在该函数中将接受请求,并fork子进程来处理。
public static void main(String argv[]) { try { ... registerZygoteSocket(); ... preload(); ... if (argv[1].equals("start-system-server")) { startSystemServer(); } else if (!argv[1].equals("")) { throw new RuntimeException(argv[0] + USAGE_STRING); } Log.i(TAG, "Accepting command socket connections"); runSelectLoop(); closeServerSocket(); } catch (MethodAndArgsCaller caller) { caller.run(); } catch (RuntimeException ex) { Log.e(TAG, "Zygote died with exception", ex); closeServerSocket(); throw ex; } } |
4. 最后我们看一下,如何启动SystemServer。
在startSystemServer()中,进入handleSystemServerProcess(…)。最终调用的是RuntimeInit.zygoteInit(…),这个函数会执行一些通用的初始化,最后通过applicationInit(…)调用com.android.server.SystemServer的main函数。
5. SystemServer会开启一个ServerThread线程,在该线程中启动一系列服务后,最后会通过ActivityManagerService.self().systemReady(…) -> resumeTopActivityLocked->startHomeActivityLocked启动Home Activity,即Launcher。
转载于:https://my.oschina.net/fuyajun1983cn/blog/263817
Zygote启动分析相关推荐
- 图解Android - Zygote, System Server 启动分析
Init 是所有Linux程序的起点,而Zygote于Android,正如它的英文意思,是所有java程序的'孵化池'(玩过星际虫族的兄弟都晓得的).用ps 输出可以看到 >adb shell ...
- Zygote启动流程及源码分析
1 Zygote是什么 在Android中,负责孵化新进程的这个进程叫做Zygote,安卓上其他的应用进程都是由zygote孵化的.众所周知,安卓是Linux内核,安卓系统上运行的一切程序都是放在Da ...
- 【Android 性能优化】应用启动优化 ( 安卓应用启动分析 | Launcher 应用启用普通安卓应用 | 应用进程分析 )
文章目录 一. Launcher 应用 startActivitySafely 方法分析 二. Launcher 中的 startActivity(View v, Intent intent, Obj ...
- Android6.0源码分析—— Zygote进程分析(补充)
原文地址: http://blog.csdn.net/a34140974/article/details/50915307 此博文为<Android5.0源码分析-- Zygote进程分析> ...
- Android5.0源码分析—— Zygote进程分析
1 Zygote简介 Android的应用程序一般都是由Java语言编写而成的,这样的应用程序需要运行在独自的Dalvik虚拟机之上(当然,5.0好像默认了ART了).但是,如果在每一个进程 ...
- android6.0源码分析之Zygote进程分析
在android6.0源码分析之Runtime的初始化一文中,对Zygote进程的初期的Runtime初始化过程进行了分析,在Runtime启动结束后,会对Zygote进程进行初始化,其它Java进程 ...
- zygote启动过程
作者:贾东风 1. zygote是什么? 在 Android 系统中,JavaVM(Java 虚拟机).应用程序进程以及运行系统关键服务的 SystemServer 进程都是由 Zygote 来创建的 ...
- Zygote启动及其作用
目录 1.Zygote简介 2.Zygote进程如何启动 2.1 init.zygote64_32.rc文件 2.2 查看ps信息 2.3 启动 3.Zygote作用 3.1 启动system_ser ...
- Android Framework——zygote 启动 SystemServer
概述 在Android系统中,所有的应用程序进程以及系统服务进程SystemServer都是由Zygote进程孕育(fork)出来的,这也许就是为什么要把它称为Zygote(受精卵)的原因吧.由于Zy ...
最新文章
- android动态设置错误页面,Android中替换WebView加载网页失败时的页面
- const与readonly,析构函数,虚拟方法
- 自己动手搭建DNS服务器
- neo4jd3的使用流程(转载)
- 免费使用的支付宝,到底是怎么一年赚1206亿的?
- 分布式定时任务框架Elastic-Job的使用
- morse java_华威MORSE,华威数统那个比较好?
- iphone label初始化碰到的问题
- android中sharedPreferences的用法
- R语言分类算法之线性判别分析(Linear Discriminant Analysis)
- AndroidStudio_安卓原生开发_在Androidstudio中查看设备管理器---Android原生开发工作笔记160
- Android 样式
- windows批处理命令大全
- UE4/UE5 WebBrowser无法播放直播流的问题
- JavaScript 技术篇-如何实现在线logo网站制作后的logo去水印,免费制作无水印logo方法
- java 表格_Java创建表格实例详解
- vs2019+opencv环境配置
- 元宇宙产业委通过央链直播召开第十次新闻通报会:第十一批入会成员名单公布
- STM32电子钟万年历Proteus仿真_LCD1602显示
- numpy.arange()函数解析
热门文章
- buffers和cache的区别
- 对使用Jolt调用Tuxedo的一个简单的封装
- 程序与生活:程序员要保持好奇心
- 2010年7月微软最有价值专家(MVP)当选名单
- AMD与intel CPU型号大全(接口)
- A 元素[HTML 4.01]
- [Gdal-dev] GCP's, Warping and Source Data Projections
- 【例题收藏】◇例题·6◇ 电压机制(voltage)
- 编写更好的 Java 单元测试的 7 个技巧
- JavaCore/HeapDump文件及其分析方法