了解Android:Zygote和DalvikVM
我试图了解Android如何推广应用程序。 问题是如何zygote正好分叉Dalvik虚拟机。 我真的不明白为什么不能在同一个Dalvik虚拟机上运行多个应用程序。
不,Dalvik不跨越stream程。
然而,活页夹IPC机制可以做一个非常令人信服的工作,使物体似乎迁移到一个不同的过程和它的Dalvik实例。 而且,内存pipe理在所有需要它们的进程中共享只读页面是非常好的。 托pipe一个典型应用程序的Dalvik进程与zygote分离,所有已经映射的常见Android库,所以新的唯一副本不必打开。
来源: 使用多个进程的应用程序共享一个Dalvik实例吗?
另外检查这些链接:
http://davidehringer.com/software/android/The_Dalvik_Virtual_Machine.pdf
Q. zygote如何正确分叉Dalvik VM?
简答: Zygote进程基本上冷启动系统上的一个虚拟机启动。 一旦完成,它将侦听传入命令的套接字。 其他进程(例如ActivityManagerService)只要需要应用程序的新进程就将命令写入此套接字。 这个命令被Zygote进程读取并调用fork() – 所以subprocess现在获得一个预热的虚拟机来运行。 这就是合子如何分叉Dalvik虚拟机。
长答案:(这可能会很长)内核加载后, init.rc
被parsing,并启动本地服务。 通过这个,运行/system/bin/app_process
(源代码: frameworks / base / cmds / app_process / app_main.cpp )。 这最终会调用AndroidRuntime.start()
函数(源代码: frameworks / base / core / jni / AndroidRuntime.cpp ),并传递参数com.android.internal.os.ZygoteInit
和start-system-server
。
AndroidRuntime.start()
启动Java VM,然后调用ZygoteInit.main()
(源代码: frameworks / base / core / java / com / android / internal / os / ZygoteInit.java ),将参数start-system-server
。
ZygoteInit.main()
首先注册ZygoteInit.main()
套接字( ZygoteInit.main()
进程侦听传入命令的套接字,并在接收到新命令时根据请求生成一个新进程)。 接下来发生的事情是,它预先加载了很多类(在frameworks / base / preloaded-classes中列出,最后我在android 4.0.4中检查了2307行)以及所有系统资源(如drawable,xmls,然后调用startSystemServer()
,为com.android.server.SystemServer
(源代码: frameworks / base / services / java / com / android / server / SystemServer.java ) startSystemServer()
一个新的进程。 系统服务器分叉是个特例,因为在所有其他情况下,zygote进程监听一个套接字,并分支出新的命令,我们很快就会看到。
SystemServer分叉后,调用一个函数runSelectLoopMode()
。 这是一个while(true)
循环,它基本上与ZygoteConnection
套接字build立一个ZygoteConnection
,并等待其上的命令。 当收到一个命令时, ZygoteConnection.runOnce()
(源代码: frameworks / base / core / java / com / android / internal / os / ZygoteConnection.java )
ZygoteConnection.runOnce()
调用Zygote.forkAndSpecialize()
(源代码: libcore / dalvik / src / main / java / dalvik / system / Zygote.java ),它只需调用一个natvie函数来执行fork。 因此,就像在SystemServer的情况下一样,一个subprocess被创build,其本身已经预热了Dalvik。
问:为什么不能在同一个Dalvik虚拟机上运行多个应用程序?
据我所知,这是一个devise决定。 Android人员决定为每个进程分配一个新的虚拟机,以便通过沙盒进行安全性。
Zygote也被用来与所有的应用程序共享系统drawables。 这允许系统仅加载一次button的位图。
只是当zygote在接收到一个命令时做了一个分支之后,再添加一个点来回答上面的问题,它使用了写时复制技术 。 仅在新进程尝试修改内存时才复制内存。
另外zygote在启动时加载的核心库是只读的 ,不能被修改。 所以它们不被复制,而是与新的分叉进程共享 。
所有这些都导致了快速启动和更less的内存占用 。
Zygote与Dalvik没有什么联系,只是一个初始化过程。 Zygote是Android用来启动应用程序的方法。 而不必从头开始每个新的过程,每当你想要启动一个应用程序时,重新加载整个系统和Android框架,它会执行一次处理,然后在Zygote完成任何特定应用程序之前停止。 然后,当你想启动一个应用程序时,Zygote进程分叉,并且subprocess继续停下来,将应用程序本身加载到VM中。