了解 Android:Zygote 和 DalvikVM
我想了解 Android 如何启动应用程序。问题是 Zygote 如何(以及为什么)分叉一个新的 Dalvik VM?我不明白为什么不能在同一个 Dalvik VM 中运行多个应用程序。
I am trying to understand how Android launches applications. The question is how (and why) does the Zygote fork a new Dalvik VM? I do not understand why it is not possible to run multiple applications in the same Dalvik VM.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
简短回答:
Zygote 进程在系统启动时冷启动 Java VM。然后它侦听套接字以获取传入命令。每当应用程序需要新进程时,其他进程(例如 ActivityManagerService)都会向此套接字写入命令。这些命令由 Zygote 进程读取,并根据需要调用 fork()。子进程获得一个预热的虚拟机来运行。这就是 Zygote 分叉 Dalvik VM 的方式。
长答案:加载内核后,将解析
init.rc
并启动本机服务。然后/system/bin/app_process< /code>
) 已运行。这最终会调用
AndroidRuntime.start ()
,向其传递参数com.android.internal.os.ZygoteInit
和start-system-server
。AndroidRuntime.start()
启动 Java VM,然后调用ZygoteInit.main()
,向其传递参数启动系统服务器
。ZygoteInit.main()
注册 Zygote 套接字(Zygote 进程侦听传入命令,并在接收新命令时根据请求生成一个新进程)。然后它会预加载很多类(如 frameworks/base/ 中列出的)预加载类,在 Android 8.0 中超过 4500 个)以及所有系统范围的资源,如可绘制对象、xml 等。然后它调用startSystemServer()
为com.android.server.SystemServer
。该分叉很特殊,其执行方式与 Zygote 代表请求进程执行的常规分叉不同。SystemServer 分叉后,将调用 runSelectLoopMode() 函数。这是一个 while(true) 循环,它与 Zygote 套接字建立一个 ZygoteConnection 并等待其上的命令。收到命令时,
ZygoteConnection.runOnce()
被调用。ZygoteConnection.runOnce()
然后调用Zygote.forkAndSpecialize()
然后调用本机函数来执行实际操作 叉。因此,与 SystemServer 的情况一样,会创建一个子进程,该子进程会为其自身继承预热的 Dalvik VM。据我所知,这是一个设计决定。 Android 人员刚刚决定通过沙箱为每个进程分叉一个新的虚拟机以确保安全。
Short Answer:
The Zygote process cold boots a Java VM on system start up. It then listens to a socket for incoming commands. Other processes (e.g. ActivityManagerService) write commands to this socket whenever a new process is needed for an application. These commands are read by the Zygote process which calls fork() as necessary. Child processes get a pre-warmed VM in which to run. This is how Zygote forks the Dalvik VM.
Long answer: After the kernel is loaded,
init.rc
is parsed and native services are started. Then/system/bin/app_process
) is run. This eventually callsAndroidRuntime.start()
, passing it the parameterscom.android.internal.os.ZygoteInit
andstart-system-server
.The
AndroidRuntime.start()
starts a Java VM then callsZygoteInit.main()
, passing it the parameterstart-system-server
.ZygoteInit.main()
registers the Zygote socket (which the Zygote process listens to for incoming commands, and on receiving new command, spawns a new process as requested). It then preloads a lot of classes (as listed in frameworks/base/preloaded-classes, over 4500 in Android 8.0) and all the system-wide resources like drawables, xmls, etc. Then it callsstartSystemServer()
which forks a new process forcom.android.server.SystemServer
. This fork is special and is not done in the same manner as the usual forks the Zygote performs on behalf of requesting processes.After SystemServer is forked the
runSelectLoopMode()
function is called. This is awhile(true)
loop which establishes aZygoteConnection
with the Zygote socket and waits for commands on it. When a command is received,ZygoteConnection.runOnce()
is called.ZygoteConnection.runOnce()
then callsZygote.forkAndSpecialize()
which then calls a native function to do the actual fork. Thus, like in the case of SystemServer, a child process is created which inherits a pre-warmed Dalvik VM for itself.This is a design decision as far as I know. The Android guys just decided to fork a new VM per process for security via sandboxing.
来源:使用多个进程的应用程序是否共享 Dalvik 实例?
另请检查这些链接:
http://davidehringer.com/software/android/The_Dalvik_Virtual_Machine.pdf
http://commonsware.com/blog/Articles/what-is-dalvik.html
Source: Do apps using multiple processes share a Dalvik instance?
Also check these links:
http://davidehringer.com/software/android/The_Dalvik_Virtual_Machine.pdf
http://commonsware.com/blog/Articles/what-is-dalvik.html
Zygote 还用于与所有应用程序共享系统绘图。
这允许系统只加载一次按钮的位图
实例。
Zygote is also used to share the system drawables with all the apps.
This allows the system to load the bitmaps for buttons only once for
instance.
只是为了在上面的答案中再添加一点,当 zygote 在接收命令时进行分叉时,它使用写时复制技术。仅当新进程尝试修改内存时才会复制内存。
此外,zygote 在启动时加载的核心库是只读且无法修改。因此,它们不会被复制,而是与新的分叉进程共享。
所有这些都带来了快速启动和更少的内存占用。
Just to add one more point to answers above when zygote does a fork on receiving a command it uses copy-on-write technique. Memory is copied only when the new process tries to modify it.
Also the core libraries that zygote loads on startup are read only and cannot be modified. So they are not copied over but shared with new forked processes.
All of these led to quick startup and less memory footprint.
Zygote 与 Dalvik 并没有真正的联系,它只是一个 init 进程。 Zygote 是 Android 用来启动应用程序的方法。不必从头开始每个新进程,每次要启动应用程序时都重新加载整个系统和 Android 框架,而是在 Zygote 执行任何特定于应用程序的操作之前执行该进程一次,然后在该点停止。然后,当您想要启动应用程序时,Zygote 进程会分叉,子进程会从中断处继续,将应用程序本身加载到 VM 中。
Zygote isn't really bound up with Dalvik, it's just an init process. Zygote is the method Android uses to start apps. Rather than having to start each new process from scratch, loading the whole system and the Android framework afresh each time you want to start an app, it does that process once, and then stops at that point, before Zygote has done anything app-specific. Then, when you want to start an app, the Zygote process forks, and the child process continues where it left off, loading the app itself into the VM.