了解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

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

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.ZygoteInitstart-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中。