Framework - Zygote

news2024/9/24 21:21:24

一、概念

Zygote是 Android 中的第一个进程,负责孵化(fork)其它进程,而它自己由 Linux 内核启动的用户级进程 Init 创建。

二、作用

        应用程序不能直接以本地进程的形态运行,必须在一个独立的虚拟机中运行,一些系统资源每个APP都会用到,如果每次都重新启动一个虚拟机,将严重拖慢应用程序的启动速度。

        Linux 中 fork 出的子进程与父进程共享内存资源(子进程能访问父进程资源),只有当子进程改写内存时,操作系统才会为其分配一个新页面,并将老页面上的数据复制一份到新页面,这就是写时拷贝机制(Copy On Write,fork操作不会将进程中所有线程拷贝,只会拷贝当前线程)。

        Zygote进程在初始化时会创建虚拟机并加载一些APP都会用到的系统资源,这样 fork 出的子进程能共享这些资源,接下来只需装载 apk 文件的字节码就可以运行应用程序了,可以大大缩短应用的启动时间。

三、启动过程

60217847d1154b6aa634f5889c07a818.png

3.1 init.rc

入口:system/core/rootdir/init.rc

Zygote进程由 Linux 中的 init 进程解析 init.rc 文件(Linux命令脚本)以 Service 的方式启动,根据系统属性 ro.zygote 的具体值,加载不同的描述Zygote的rc脚本。

3.2 Native中

入口main函数:frameworks/base/cmds/app_process/app_main.cpp

最初名字叫“app_process”,这个名字是在Android.mk文件中指定的,但是在运行过程中Linux下的pctrl系统调用将名字换成了“zygote”。

int main(int argc, char* const argv[]) {
    //创建虚拟机
    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    //解析 init.rc 中的参数
    while(i < argc) {...}
    //app_process改名zygote
    runtime.setArgv0(niceName.string(), true);
    //执行ZygoteInit切换到Java世界
    if(zygote) {
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    }
}
  • 创建虚拟机:
  • 注册Android的JNI函数:
  • 进入到Java世界:

3.3 Java中

入口main函数:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public static void main(String argv[]) {
    //创建Server端的Socket用来通信
    zygoteServer.registerServerSocket(socketName);
    //预加载类和资源
    preload(bootTimingsTraceLog);
    //开启SystemService
    forkSystemServer(abiList, socketName, zygoteServer);
    //开启死循环监听Client端的消息
    zygoteServer.runSelectLoop(abiList);
}
  • 建立Socket通信:创建一个Server端的Socket用于Zygote与其它进程通信。(ANDROID_SOCKET_zygote,一旦有新进程需要执行系统就通过这个 socket 跟 zygote 通信)。
  • 预加载类和资源:常用类文件、Resources资源、HALs资源、opengl、webview等一般都是只读的不会进行修改,而且是很多应用都可能会用到的,因此预先加载后,通过 Zygote 孵化出的进程共享虚拟机内存和框架层资源,这样大幅度提高应用程序的启动和运行速度。(类加载机制:加载子类都会先加载父类。被大量APP继承的基类就不会每次都要加载如AppCompatActivity)。
  • 启动SystemService
  • 开启Loop循环:等待 Client 端消息去创建应用进程。

 通讯机制 Socket

进程间通信是一对多模型,支持C/S(Client-Server)架构的只有 Socket 和 Binder,而采用 Socket 而不是 Binder 是因为:

  • Binder 机制复杂:首先zygote要启用binder机制,需要打开binder驱动,获得一个描述符,再通过mmap进行内存映射,还要注册binder线程,这还不够,还要创建一个binder对象注册到serviceManager,另外AMS要向zygote发起创建应用进程请求的话,要先从serviceManager查询zygote的binder对象,然后再发起binder调用,这来来回回好几趟非常繁琐,相比之下,zygote和SystemServer进程本来就是父子关系,对于简单的消息通信,用管道或者socket非常方便省事。
  • 隔离:如果zygote启用binder机制,再fork出SystemServer,那么SystemServer就会继承了zygote的描述符以及映射的内存,这两个进程在binder驱动层就会共用一套数据结构,这显然是不行的,所以还得先给原来的旧的描述符关掉,再重新启用一遍binder机制,这个就是自找麻烦了。
  • 性能问题:开进程是一个效率低的事情(处理慢),而Binder是一个传输效率高的机制(请求快),假如一下子开10个进程会导致请求都堵在那里,从200M飙到2G打乱系统内存分配。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/658087.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Springboot实现数据传输加解密

前言 先给大家看下效果&#xff0c;原本我们的请求是这样子的 加密后的数据传输是这样子的 加解密步骤&#xff1a; 1.前端请求前进行加密&#xff0c;然后发送到后端 2.后端收到请求后解密 3.后端返回数据前进行加密 4.前端拿到加密串后&#xff0c;解密数据 加解密算法&…

搭建TiDB负载均衡环境-LVS+KeepAlived实践

作者&#xff1a; 我是咖啡哥 原文来源&#xff1a; https://tidb.net/blog/f614b200 昨天&#xff0c;发了一篇使用HAproxyKP搭建TiDB负载均衡环境的文章&#xff0c;今天我们再用LVSKP来做个实验。 环境信息 TiDB版本&#xff1a;V7.1.0 haproxy版本&#xff1a;2.6.2 …

【EXCEL】如何查找特殊字符 问号‘?’星号 ‘*’

目录 0.环境 1.适用场景 1&#xff09;直接搜索问号的结果&#xff1a; 2&#xff09;修改【查找内容】后&#xff0c;搜索结果变为精准定位&#xff1a; 2.具体做法 0.环境 windows wps&#xff08;或excel&#xff0c;这里试了&#xff0c;此问题wps和excel表格是通用…

chatgpt赋能python:Python如何计算圆周率π

Python如何计算圆周率π 圆周率&#xff0c;又称π&#xff0c;是数学中一个重要的常数&#xff0c;它与圆的周长和直径的比值始终保持不变。在计算机编程中&#xff0c;计算圆周率π也是一个颇具挑战的问题。本文介绍了使用Python编程语言来计算圆周率π的方法&#xff0c;希…

C语言进阶---指针的进阶

前言 指针的主题&#xff0c;我们在初级阶段的《指针》章节已经接触过了。我们直到指针的概念。 ​ 1、指针就是个变量&#xff0c;用来存放地址&#xff0c;地址唯一标识一块内存空间。 ​ 2、指针的大小是固定的4/8个字节&#xff08;32为平台/64位平台&#xff09; ​ 3、指…

chatgpt赋能python:Python如何输出Unicode:一位10年编程经验的工程师的经验分享

Python如何输出Unicode&#xff1a;一位10年编程经验的工程师的经验分享 Python是一种常见的编程语言&#xff0c;被广泛应用于各种文本处理任务。其中一个有趣的方面是Python与Unicode的集成。在这篇博客文章中&#xff0c;我将分享我的经验&#xff0c;介绍如何在Python中输…

查看当前编译器(或交叉编译器)支持的C/C++标准

如果已经配置到系统环境中则直接使用&#xff1b; 如果没有配置到系统环境中&#xff0c;找到当前使用的交叉编译器的路径&#xff1b; gcc -E -dM - </dev/null | grep "STDC_VERSION" 或者编写一段小代码&#xff1a; printf("%ld\n",__STDC_VERS…

【栈与队列part02】| 20.有效的括号、1047.删除字符串中所有相邻重复项、150.逆波兰表达式求值

目录 ✿LeetCode20. 有效的括号❀ ✿LeetCode1047.删除字符串中的所有相邻重复项❀ ✿LeetCode150. 逆波兰表达式求值❀ ✿LeetCode20. 有效的括号❀ 链接&#xff1a;20.有效的括号 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;]…

rust 使用第三方库构建mini命令行工具

这是上一篇 rust 学习 - 构建 mini 命令行工具的续作&#xff0c;扩展增加一些 crate 库。这些基础库在以后的编程工作中会常用到&#xff0c;他们作为基架存在于项目中&#xff0c;解决项目中的某个问题。 项目示例还是以上一篇的工程为基础做调整修改ifun-grep 仓库地址 怎…

Linux MTD子系统(二)——mtdblock驱动分析

在之前的文章Linux MTD子系统(一)中有提到过mtd块设备&#xff0c;mtd块设备是在MTD设备之上模拟的块设备。 它的作用实际上只有一个——便于我们使用mount(umount)挂载(卸载)MTD设备中的文件系统&#xff0c;例如yaffs2&#xff0c;JFFS2等等。 本文将介绍mtdblock是如何实现…

LIN总线协议-调度表

文章目录 一、调度表只有一个调度表时&#xff0c;采用循环执行三个调度表存在时&#xff0c;顺序执行调度表发生中断 二、总结 一、调度表 调度表规定了总线上帧的传输次序&#xff08;调度Header&#xff09;以及各帧在总线上的传输时间。 调度表位于主机节点&#xff0c;主…

算法刷题-字符串-左旋转字符串

反转个字符串还有这么多用处&#xff1f; 题目&#xff1a;剑指Offer58-II.左旋转字符串 力扣题目链接 字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如&#xff0c;输入字符串"abcdefg"和数字2…

C++算法:单源最短路径Dijkstra

文章目录 前言一、Dijkstra算法思想二、算法实现1、建立图2、代码实现 总结 前言 如果你有一份北京地图&#xff0c;想从中关村走到三元桥&#xff0c;那么怎样能找出实现这一目的的最短路径呢?一种可能的方法就是将这两点之间所有的路线都找出来&#xff0c;然后求出每条路线…

openSUSE项目近日宣布openSUSE Leap 15.5的发布和全面供应

openSUSE项目近日宣布openSUSE Leap 15.5的发布和全面供应&#xff0c;该版本是openSUSE变体的最新稳定版本&#xff0c;针对那些希望为其个人电脑提供基于SUSE Linux Enterprise 15的经过良好测试的操作系统的用户。 openSUSE Leap 15.5是在openSUSE Leap 15.4的一年后推出的&…

Vue中如何进行音频可视化与音频频谱展示

Vue中如何进行音频可视化与音频频谱展示 随着音频应用程序的不断发展&#xff0c;音频可视化和音频频谱展示成为了重要的功能。在Vue应用程序中实现音频可视化和音频频谱展示可以帮助用户更好地了解音频文件的内容和特征。本文将介绍如何在Vue应用程序中实现音频可视化和音频频…

Opensearch基本介绍

OpenSearch 是一个社区驱动的开源搜索和分析套件&#xff0c;开发人员使用该套件来摄取、搜索、可视化和分析数据。 OpenSearch 由数据存储和搜索引擎 (OpenSearch)、可视化和用户界面 (OpenSearch Dashboards) 以及服务器端数据收集器 (Data Prepper) 组成。 用户可以使用一系…

把数字中国,建立在行业感知的底座上

5月23日&#xff0c;国家互联网信息办公室发布了《数字中国发展报告&#xff08;2022年&#xff09;》。报告显示&#xff0c;2022年中国数字经济规模达到50.2万亿元&#xff0c;占国内生产总值比重提升至41.5%&#xff0c;总量居世界第二。如今数字中国最主要的发展挑战&#…

MIFARE - 1

2一般说明 飞利浦根据ISO/IEC 14443A开发了用于非接触式智能卡的MIFAREMF1 IC S50。通信层&#xff08;MIFARERF接口&#xff09;符合ISO/IEC 14443A标准的第2部分和第3部分。安全层采用经过现场验证的CRYPTO1流密码&#xff0c;用于MIFAREClassic系列的安全数据交换。 MIFARE…

GPT中的temperature参数不是用在对话的而是用在调用OPEN API过程中的

前言 自从吴恩达OPENAI《ChatGPT 提示工程》放出后,各个层面反响热列。很多人看到了temperature这个参数,都以为在对话中或者说对话的末尾放上一个temperature=0-2的值就可以达到让GPT极大的发挥出自我创造能力、甚至写文章天马行空。 笔者这边觉得有义务指出这种用法是完全…

OpenAI ChatGPT 使用示例(程序员)

1.编程应用 1.1. 生成例子代码(Coding Generation) ChatGPT帮助我们生产我们需要的例子代码。而且准确率很高。即使你不懂某一种语言也没关系&#xff0c;一定程度上较低了程序员的的门槛。 我有三组数据&#xff0c;第一组是星期一到星期五&#xff0c;第二组是这一天的具体…