android jni fork()子进程不运行_Android高级面试谈谈Zygote的理解
Zygoto的作用
Zygoto的作用有兩個:
1. 啟動SystemServer
2. 孵化應用進程
SystemServer也是通過Zygoto來啟動的,因為SystemServer需要Zygoto初始化好的一些系統資源,包括常用的類、JNI函數、共享庫等等,這些資源直接從Zygoto繼承過來對啟動SystemServer是一件性能提升的事情。
Android中進程啟動的通用流程 - 啟動三段式
進程啟動 -> 準備工作 -> Loop循環
Loop循環的作用是為了接收消息并處理消息。在Android中,所有的獨立進程的啟動都是符合這個啟動流程的。
Zygoto的啟動流程
Linux啟動之后,用戶空間的第一個進程是Init進程,Init進程在啟動之后會去讀取init.rc的啟動配置文件,其中定義了需要啟動的系統進程(其中包含Zygoto進程)。Init進程啟動Zygoto的方式是fork + execve的方式。
進程啟動通常有兩種方式:
1. fork + handle
2. fork + execve
【說明】
1. fork函數在創建進程的時候,會返回兩次,返回兩個pid,當pid = 0的時候,說明當前處于子進程,當pid不為0表示當前處于父進程中,而此時的pid為子進程的pid;
2.fork函數創建的進程繼承了父進程所有的系統資源,我們在fork出的子進程中調用execve方法加載二進制文件可以重置繼承自父進程的系統資源。
信號處理 - SIGCHLD
父進程通過fork創建的子進程,當子進程掛了之后,父進程會收到一個SIGCHLD的信號,此時我們就可以在父進程中重啟子進程。
Zygoto在創建之后做了些什么
1. Zygoto在native世界
2. Zygoto在Java世界
Zygoto是C++編寫的,通過main函數入口運行,Zygoto在native做了3件事情,這3件事情都是為了進入Java世界作準備:
從上圖可以看到,Zygoto啟動之后,首先啟動Android的虛擬機,然后注冊一些Android的關鍵的JNI函數,最后通過調用JNI函數進入Java世界。
上面的代碼就是Zygoto啟動之后做的事情,從上面的代碼可以看到,Zygoto首先通過JNI_CreateJavaVM創建虛擬機,在找到ZygotoInit的Java類文件,并獲取到該Java類的Main靜態函數,最后通過CallStaticVoidMethod方法調用Java類ZygotoInit的Main靜態方法。
我們在應用進程中調用JNI的時候,是不需要創建虛擬機的,即不需要調用JNI_CreateJavaVM方法,這是因為虛擬機已經在Zygoto中創建完畢,且應用進程是有Zygoto孵化的,應用進程繼承了Zygoto所有的系統資源,同樣包含虛擬機,所以在應用進程中調用JNI函數前,無需再次調用JNI_CreateJavaVM來創建虛擬機。
Zygoto在Java世界中要做的事情有3件:
1. 加載資源,這是為了在后續孵化子進程的時候,可以將加載的系統資源繼承給子進程;
2. 通過fork函數孵化SystemServer進程
3. 啟動Loop循環,接收并處理Socket消息
Zygoto啟動Loop循環之后,會接收Socket消息,每次接收到Socket消息之后,就會調用runOnce方法處理消息:
上面的代碼是Loop中一次消息處理的過程,首先會通過readArgumentList方法讀取本次通過Socket傳遞過來的參數,然后fork啟動一個子進程,再在子進程中處理參數。
子進程是通過handleChildProc方法來處理參數,handleChildProc本質上就是調用某個Java類的main函數,執行的是哪個Java類呢,執行的Java類的名稱是通過AMS(Activity Manager Server)借助Socket發過來的,此處通過readArgumentList讀取到的。
注意的細節:
1. Zygoto fork需要單進程
Zygoto通過fork創建的子進程中只包含一個線程,而Zygoto中包含多個線程(e.g. 守護線程等等),這些多余的線程在創建完成的子線程中是不存在的,就會造成子進程中狀態的錯誤,所以在Zygoto fork新的子進程的時候,會將所有主線程以外的子線程全部暫停,fork完畢之后,再啟動所有的子線程。
2. Zygoto的IPC(跨進程通宵)沒有采用Binder機制,而是使用本地的Socket服務。Zygoto進程并沒有Binder機制,所以Zygoto創建的應用進程中也沒有繼承到Binder,應用進程的Binder是應用進程啟動之后自己創建啟動的。
總結
以上是生活随笔為你收集整理的android jni fork()子进程不运行_Android高级面试谈谈Zygote的理解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle 更新记录语句,Oracle
- 下一篇: oracle 重建em失败,11gr2