理解Android:合子和DalvikVM

理解Android:合子和DalvikVM,android,dalvik,Android,Dalvik,我试图了解Android是如何启动应用程序的。问题是合子如何(以及为什么)产生新的Dalvik VM?我不明白为什么不能在同一个Dalvik VM中运行多个应用程序 不,Dalvik不跨流程 然而,Binder IPC机制可以非常令人信服地使对象看起来迁移到不同的进程及其Dalvik实例。此外,内存管理非常适合在所有需要只读页的进程之间共享只读页。Dalvik进程承载着一个典型的应用程序,它与所有常用的android库都已映射,因此不必打开新的独特副本 资料来源: 同时检查以下链接: 合子还用

我试图了解Android是如何启动应用程序的。问题是合子如何(以及为什么)产生新的Dalvik VM?我不明白为什么不能在同一个Dalvik VM中运行多个应用程序

不,Dalvik不跨流程

然而,Binder IPC机制可以非常令人信服地使对象看起来迁移到不同的进程及其Dalvik实例。此外,内存管理非常适合在所有需要只读页的进程之间共享只读页。Dalvik进程承载着一个典型的应用程序,它与所有常用的android库都已映射,因此不必打开新的独特副本

资料来源:

同时检查以下链接:


合子还用于与所有应用程序共享系统绘图。 这允许系统仅为按钮加载一次位图 例如

合子是如何确切地分叉Dalvik VM的

简短回答: Zygote进程在系统启动时冷引导JavaVM。然后,它侦听套接字以获取传入命令。当应用程序需要新进程时,其他进程(如ActivityManagerService)会将命令写入此套接字。这些命令由zyote进程读取,该进程根据需要调用fork()。子进程获得一个预热的VM,在其中运行。这就是合子分叉Dalvik VM的方式

详细回答:加载内核后,
init.rc
被解析并启动本机服务。然后)运行。这最终会调用,并向其传递参数
com.android.internal.os.ZygoteInit
start system server

AndroidRuntime.start()
启动Java虚拟机,然后调用,并向其传递参数
start system server

ZygoteInit.main()
注册Zygote套接字(Zygote进程侦听该套接字以获取传入命令,并在收到新命令时根据请求生成新进程)。然后它预加载很多类(如中所列,Android 8.0中超过4500个)和所有系统范围的资源,如drawables、xmls等。然后它调用
startSystemServer()
,为其派生一个新的进程。这个分叉是特殊的,与受精卵代表请求进程执行的通常分叉不同

在SystemServer分叉后,将调用
runSelectLoopMode()
函数。这是一个
while(true)
循环,它与合子套接字建立
合子连接
,并等待命令。当收到命令时,调用

ZygoteConnection.runOnce()
然后调用该函数,然后调用本机函数来执行实际的fork操作。因此,与SystemServer的情况一样,创建了一个子进程,它为自己继承了一个预热的Dalvik VM

问:为什么不能在同一台计算机上运行多个应用程序 达尔维克虚拟机


据我所知,这是一个设计决定。Android的家伙们刚刚决定通过沙箱为每个进程提供一个新的VM,以确保安全性。

Zygote与Dalvik并没有真正的联系,它只是一个初始化进程。合子是Android用来启动应用程序的方法。它不必从头开始每一个新的过程,每次你想启动一个应用程序时都重新加载整个系统和Android框架,而是在Zygote完成任何特定于应用程序的操作之前,先执行一次该过程,然后在该点停止。然后,当您想要启动一个应用程序时,Zygote进程分叉,子进程继续它停止的地方,将应用程序本身加载到VM中。

只需在上面的答案中添加一点,当Zygote在接收到它使用的写时复制技术时分叉。只有当新进程尝试修改内存时,才会复制内存

另外,启动时合子加载的核心库是只读的,不能修改。因此,它们不是复制过来的,而是与新的分叉过程共享的


所有这些都导致了快速启动更少的内存占用

,这两方面都有所减少:Zygote加载了一个底层版本的OpenSSL。一个希望加载OpenSSL版本的应用程序通常会被底层版本卡住,因为Zygote在fork之前已经加载了它。这包括支持FIPS的OpenSSL版本,该应用程序正在尝试使用经过验证的加密技术。关于“Q.为什么不可能在同一个Dalvik VM中运行多个应用程序?”当您要求组件在同一进程中运行时,android:process=“”是否会发生这种情况?这也可以通过使用android:sharedUserId=“”“AndroidRuntime.start()启动Java虚拟机”你不是说
Dalvik虚拟机