zygote的啓動和作用

  • zygote的作用(what)
  • zygote的啓動流程(how)
  • zygote的工作原理(why)

zygote的作用

1、啓動SystemServer
2、孵化引用進程

zygote啓動流程和工作原理

啓動進程

1、linux啓動後的第一個進程:Init進程;
2、Init進程讀取Init.rc文件開啓zygote進程;

準備工作

3、調用startVm函數創建虛擬機,調用startReg函數爲虛擬機註冊JNI方法;
4、在虛擬機的環境中找到zygoteInit的類,找到類中的Main函數,使用CallStaticVoidMethod函數開啓Main函數,從這裏就進入了java世界,上面的都是native世界;
5、zygote進程開始預加載系統資源,這樣通過它fork的子進程就相當於不用再創建一遍資源,達到了加速啓動應用進程的作用。
6、啓動SystemServer進程,用來啓動系統服務

Loop

7、最後開啓Loop,通過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機制,這個就是自找麻煩了。

參考資料:
談談對Android中Zygote的理解 - 掘金

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章