了解Android:Zygote和DalvikVM

时间:2012-02-05 21:24:57

标签: android dalvik

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

5 个答案:

答案 0 :(得分:130)

  

Q值。 zygote如何正确分叉Dalvik VM?

简答: Zygote进程在系统启动时冷启动Java VM。然后它监听套接字以获取传入的命令。只要应用程序需要新进程,其他进程(例如ActivityManagerService)就会向此套接字写入命令。这些命令由Zygote进程读取,该进程根据需要调用fork()。子进程获得要运行的预热VM。这就是Zygote如何分配Dalvik VM。

长答案:加载内核后,将解析init.rc并启动本机服务。然后运行/system/bin/app_process)。这最终会调用AndroidRuntime.start(),并将参数com.android.internal.os.ZygoteInitstart-system-server传递给它。

AndroidRuntime.start()启动Java VM,然后调用ZygoteInit.main(),并将参数start-system-server传递给它。

ZygoteInit.main()注册Zygote套接字(Zygote进程侦听传入命令,并在接收新命令时,根据请求生成新进程)。然后它会预加载很多类(如frameworks/base/preloaded-classes中所列,在Android 8.0中超过4500)和所有系统范围的资源,如drawables,xmls等。然后它调用startSystemServer(),它会分叉一个新的进程为com.android.server.SystemServer。这个fork是特殊的,并不像Zygote代表请求进程执行的常规方式那样完成。

分叉SystemServer后,将调用runSelectLoopMode()函数。这是一个while(true)循环,它与Zygote套接字建立ZygoteConnection并等待命令。收到命令后,将调用ZygoteConnection.runOnce()

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

  

Q值。为什么不可能在同一个应用程序中运行多个应用程序   Dalvik VM?

据我所知,这是一项设计决定。 Android人员刚决定通过沙盒为每个进程分配一个新的VM来保证安全性。

答案 1 :(得分:31)

  

没有。达尔维克不会跨越流程。

     

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

来源:Do apps using multiple processes share a Dalvik instance?

另请查看以下链接:

http://davidehringer.com/software/android/The_Dalvik_Virtual_Machine.pdf

http://commonsware.com/blog/Articles/what-is-dalvik.html

答案 2 :(得分:6)

Zygote还用于与所有应用共享系统drawable。 这允许系统仅为按钮加载一次位图 实例

答案 3 :(得分:3)

当zygote在接收命令时使用写时复制技术时,只需再添加一个上述答案。仅在新进程尝试修改内存时才复制内存。

zygote在启动时加载的核心库也是只读,无法修改。所以他们没有复制,而是与新的分叉流程共享

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

答案 4 :(得分:1)

Zygote与Dalvik并不紧密相关,它只是一个初始化过程。 Zygote是Android用于启动应用程序的方法。而不是必须从头开始每个新进程,每次要启动应用程序时重新加载整个系统和Android框架,它会执行一次该进程,然后在Zygote执行任何特定于应用程序之前停止。然后,当你想启动一个应用程序时,Zygote进程会分叉,子进程会从它停止的地方继续,将应用程序本身加载到虚拟机中。