对zygote的理解
一、 zygote的作用
- 启动SystemServer
SystemServer需要用于zygote准备好的一些系统资源,比如常用类、注册的JNI函数、主题资源、共享库等等,直接从zygote那继承过来,SystemServer就不用重新再加载一遍,这样对性能有很大的提升。
- 启动SystemServer
- 孵化应用进程
Loop循环就是不停的接收消息,处理消息;处理的消息可以能messageQueue里面的消息,也可能是binder驱动那边传过来的。
二、Zygote的启动流程
1. zygote进程是怎么启动的
Init进程为Linux启动后用户空间的第一个进程,Init进程启动之后,首先会加载init.rc启动配置文件,然后会查看启动配置文件定义了哪些系统服务需要启动的,zygote就是要启动的服务之一,通过fork + execve 进行启动zygote进程
启动zygote进程相关的配置:
第一行命令语句说明:
- 红色部分zygote: 表示service的名称
- 蓝色部分/system/bin/app_process:表示zygote程序路径
- 黄色部分-Xzygote /system/bin --zygote --start-system-server: 表示程序执行的参数
- Xzygote:作为虚拟机启动时所需要的参数,在AndroidRuntime.cpp中的 startVm() 函数中调用 JNI_CreateJavaVM 使用到
- /system/bin:代表虚拟机程序所在目录,因为 app_process 可以不和虚拟机在一个目录,所以 app_process 需要知道虚拟机所在的目录
- -zygote:指明以 ZygoteInit 类作为入口,否则需要指定需要执行的类名
- –start-system-server:仅在有 --zygote 参数时可用,告知 ZygoteInit 启动完毕后孵化出的第一个进程是 SystemServer
- 其他命令:后续的命令是和socket相关,名称、类型、端口号、重启后的操作等等
** 启动进程**
(1) fork + handle
pid_t pid =fork();
if (pid == 0) {// child process
} else {// parent process
}
(2) fork + execve
pid_t pid =fork();
if (pid == 0) {// child processexecve(path, argv, env);
} else {// parent process
}
2. Zygote进程启动之后做了什么?
Zygote的Native世界
(1)启动Android虚拟机(初始化运行环境,创建jvm)
(2)注册Android的JNI函数
(3)进入Java世界(调用zygoteinit.main)
Zygote的Java世界
(1)预加载资源 Proload Resources,比如常用类、主题资源、共享库等–>加快进程启动
(2)socket–>让别人通知我
(3)启动System Server(单独运行在一个进程中)
(4)LOOP循环
boolean runOnce() {String[] args = readArgumentList(); //读取参数列表int pid = Zygote.forkAndSpecialize(); //启动子进程if (pid == 0) {// in child handleChildProc(args, ...); //在子进程中进行相应的工作,执行该语句之后会执行ActivityThread.man()函数return true;}
}
要注意的细节
- Zygote 进行fork的时候要单线程,为了避免造成死锁或者状态不一致等问题
- Zygote的IPC(跨进程通信)没有采用binder,采用的是本地socket通信
问题: 谈谈你对zygote的理解?
What:zygote的作用是什么?
答:(1)启动System server进程,是用于管理整个Java framework层,包含ActivityManager,PowerManager等各种系统服务;
(2)孵化其他应用程序进程
How:zygote的启动流程是什么?
答:Zygote进程是由Init进程解析init.zygote.rc文件启动的,zygote所对应的可执行程序app_process,所对应的源文件是App_main.cpp,进程名为zygote。
首先执行App_main.cpp的main()函数,在这里会执行以下步骤:
1.解析命令参数,主要是–zygote 和–start-system-server。
2.调用AppRuntime.start(“com.android.internal.os.ZygoteInit”,…),启动虚拟机,注册JNI函数;
3.通过JNI调用ZygoteInit.java的main()方法,从这里开始进入Java的世界;
运行Zygote的main方法,主要执行以下步骤:
预加载 preloadClasses()、preloadResources()、preloadSharedLibraries()
forkSystemServer,最终会调用SystemServer.java的main()方法;
创建ZygoteService,进入runSelectLoop;
zygote的启动流程简单说明:
1)创建Java虚拟机;
2)为Java虚拟机注册native方法;
3)在com.android.internal.os.ZygoteInit中调用java类的主要方法;
4)加载ZygoteInit class;
5)注册zygote socket;
6)加载preload class;
7)加载preload 资源文件;
8)调用Zygote::forkSystemServer,fork一个新的进程,调用SystemServer的main方法,从而进入到java层的system_server进程的初始化流程中;
Why:zygote的工作原理是什么?(如何孵化进程以及如何进行通信)
问题1:孵化应用进程这种事为什么不交给SystemServer来做,而专门设计一个Zygote?
答:我们知道,应用在启动的时候需要做很多准备工作,包括启动虚拟机,加载各类系统资源等等,这些都是非常耗时的,如果能在zygote里就给这些必要的初始化工作做好,子进程在fork的时候就能直接共享,那么这样的话效率就会非常高。这个就是zygote存在的价值,这一点呢SystemServer是替代不了的,主要是因为SystemServer里跑了一堆系统服务,这些是不能继承到应用进程的。所以给SystemServer和应用进程里都要用到的资源抽出来单独放在一个进程里,也就是这的zygote进程,然后zygote进程再分别孵化出SystemServer进程和应用进程。
问题2: Zygote的IPC通信机制为什么使用socket而不采用binder?
答:主要原因是因为Zygote进行fork的时候要是单线程,父进程binder线程有锁,然后子进程的主线程一直在等其子线程(从父进程拷贝过来的子进程)的资源,但是其实父进程的子进程并没有被拷贝过来,造成死锁,所以fork不允许存在多线程。而非常巧的是Binder通讯偏偏就是多线程,所以干脆父进程(Zygote)这个时候就不使用binder线程。
对zygote的理解相关推荐
- Android Framework(一)--对Zygote的理解
目录 zygote的作用 zygote的启动流程 问题:启动进程有几种方式? 问题:Zygote进程启动之后做了什么? (一)先执行native函数 (二)切换到java后 问题:Zygote for ...
- 对android中Zygote的理解
谈谈对Zygote的简单理解 1. Zygote的作用 启动SystemServer 孵化应用进程 SystemServer也是通过Zygote启动的,因为它也需要Zygote的资源:常用类,JNI函 ...
- android jni fork()子进程不运行_Android高级面试谈谈Zygote的理解
Zygoto的作用 Zygoto的作用有两个: 1. 启动SystemServer 2. 孵化应用进程 SystemServer也是通过Zygoto来启动的,因为SystemServer需要Zygot ...
- [Android]从app的trace打桩原理回顾zygote的fork
在前面http://t.csdn.cn/X3l0a 的讨论中,我们了解到,系统中是通过获取属性值,来判断trace点记录是否需要打印(记录), system/core/libutils/Trace.c ...
- android zygote启动流程,Android zygote启动流程详解
对zygote的理解 在Android系统中,zygote是一个native进程,是所有应用进程的父进程.而zygote则是Linux系统用户空间的第一个进程--init进程,通过fork的方式创建并 ...
- 1.4 深入理解Zygote
4.1 概述 读者可能已经知道,Android系统存在着两个完全不同的世界: Java世界,Google放出的SDK主要就是针对这个世界的.在这个世界中运行的程序都是基于Dalvik虚拟机的Java程 ...
- 深入理解 AndroidFramework 之 Zygote 启动
文章目录 深入理解 AndroidFramework 之 Zygote 启动 1. Init 进程 2. init.rc 启动zygote 服务 3. Zygote 进程的入口函数 -- main 3 ...
- [深入理解Android卷一全文-第四章]深入理解zygote
由于<深入理解Android 卷一>和<深入理解Android卷二>不再出版,而知识的传播不应该因为纸质媒介的问题而中断,所以我将在CSDN博客中全文转发这两本书的全部内容. ...
- Android-深入理解zygote
文章目录 1. zygote 1.1 zygote分析 1.2 AppRuntime分析 1.2.0.1 创建虚拟机-startVm 1.2.0.2 注册JNI函数-startReg 1.2.1 We ...
最新文章
- [机器学习]机器学习笔记整理12-线性回归概念理解
- android开发基础_列表视图一(List View)
- PyTorch : torch.nn.xxx 和 torch.nn.functional.xxx
- STM32F10x_硬件I2C读写EEPROM(标准外设库版本)
- Nacos注册中心的部署与用法详细介绍
- 1.QT中播放视频,录音程序的编写
- 2019.04.06 电商04 模板嵌套
- CSS之文档视图(DocumentView)和元素视图(ElementView)方法
- SpringBoot2.0 基础案例(04):定时任务和异步任务的使用方式
- React中refs的理解
- Flutter之SemanticsBinding和WidgetsBindingObserver简析
- SpringBoot+thymeleaf 发送邮件
- 微信小程序盲盒系统源码 带教程
- 全能鼠标连点器之自动点击王软件
- elasticsearch 修改已存在的filed值 和 新增filed
- 【Python】:数据可视化之相关系数热力图绘制(二)(seaborn版本)
- 湖北武汉劳务员培训劳务员的现场管理建筑七大员培训
- 【Java】使用lambda表达式获取list中所有对象的某个属性以及获取特定属性的某一个对象
- Fisher Vector费舍尔向量and FIsher Kernel费舍尔核
- matlab解对流方程初值问题,对流方程——偏微分方程的数值解法
热门文章
- 默认拷贝构造函数 与 自定义拷贝构造函数
- [高可用系列|LVS]LVS详解
- London Tube伦敦地铁全面图下载
- java radiogroup_android RadioGroup实现单选以及默认选中 | 学步园
- three.js自定义材质 切线空间及阴影
- Linux读写eeprom
- Revit二次开发之移动元素【比目鱼原创】
- Oracle几种分页查询sql语句
- linux服务器怎么降低内核cpu进程,Linux性能挖潜的隐藏招数:内核CPU亲和性参数调整...
- 一文聊透数字化转型,获得企业未来生存的入场券--童亚斋