Zygote作用
1.啟動SystemServer
Zygote准備好一些常用類,JNI函數,主題資源,共享庫
2.孵化應用進程
因此, 在Android中, 應用程序運行前, 通過Zygote進程共享已運行的虛擬機的代碼與內存信息, 縮短應用程序運行所耗費的時間. 也就是說, Zygote進程會事先將應用程序要使用的Android Framework中的類與資源加載到內存中, 並組織形成所用資源的鏈接信息. 這樣, 新運行的Android應用程序在使用所需資源時不必每次形成資源的鏈接信息, 這樣就大大提升了程序的運行時間.
Zygote進程起到了預加載資源和類到虛擬機 加快啟動應用程序的作用
android大致的啟動三段式
進程啟動 -> 准備工作 -> loop循環(接收消息,處理消息 socket,messagequeue消息,binder驅動發來的消息)
1.zygote 啟動流程
Init 進程。
init.rc 定義了一些要啟動的服務, zygote是其一
紅色 服務 名稱 , 藍色 文件路徑 , 橙色 啟動參數
fork 函數 復制父進程給子進程,返回pid=0位子進程
調用app_main.cpp的main函數中的AppRuntime的start方法來啟動Zygote進程
信號處理SIGCHLD
2.啟動之后
Zygote的native世界
啟動android虛擬機->注冊Android的JNI函數->進入java世界
Zygote的java世界
preload resources->fork SystemServer 然后進入loop等待SystemServer的socket消息
【注意】
zygote fork時單線程,為了避免造成死鎖或者狀態不一致等問題
跨進程通信采用socket
孵化應用進程為什么不給SystemServer來做,而專門設計一個Zygote?
我們知道,應用在啟動的時候需要做很多准備工作,包括啟動虛擬機,加載各類系統資源等等,這些都是非常耗時的,如果能在zygote里就給這些必要的初始化工作做好,子進程在fork的時候就能直接共享,那么這樣的話效率就會非常高。這個就是zygote存在的價值,這一點呢SystemServer是替代不了的,主要是因為SystemServer里跑了一堆系統服務,這些是不能繼承到應用進程的。而且我們應用進程在啟動的時候,內存空間除了必要的資源外,最好是干干凈凈的,不要繼承一堆亂七八糟的東西。所以呢,不如給SystemServer和應用進程里都要用到的資源抽出來單獨放在一個進程里,也就是這的zygote進程,然后zygote進程再分別孵化出SystemServer進程和應用進程。孵化出來之后,SystemServer進程和應用進程就可以各干各的事了。
Zygote的IPC通信機制為什么不采用binder?如果采用binder的話會有什么問題?
第一個原因,我們可以設想一下采用binder調用的話該怎么做,首先zygote要啟用binder機制,需要打開binder驅動,獲得一個描述符,再通過mmap進行內存映射,還要注冊binder線程,這還不夠,還要創建一個binder對象注冊到serviceManager,另外AMS要向zygote發起創建應用進程請求的話,要先從serviceManager查詢zygote的binder對象,然后再發起binder調用,這來來回回好幾趟非常繁瑣,相比之下,zygote和SystemServer進程本來就是父子關系,對於簡單的消息通信,用管道或者socket非常方便省事。第二個原因,如果zygote啟用binder機制,再fork出SystemServer,那么SystemServer就會繼承了zygote的描述符以及映射的內存,這兩個進程在binder驅動層就會共用一套數據結構,這顯然是不行的,所以還得先給原來的舊的描述符關掉,再重新啟用一遍binder機制,這個就是自找麻煩了。