2012年3月16日金曜日

startActivityの深層 後編

android.os.ProcessクラスのzygoteSendArgsAndGetPid()でsocketにいろいろwriteすると、pidがreadできる。
socketのreadをしているプロセスがいて、それがforkしてpidを返している。

アプリのプロセスの親プロセスはzygote

emulatorを起動してadb shellでpsコマンドを実行すると、各プロセスの親プロセスがわかる。
PIDがプロセスID、PPIDが親プロセスのID。
# ps
USER PID PPID VSIZE RSS WCHAN PC NAME
root 1 0 268 180 c009b74c 0000875c S /init
root 2 0 0 0 c004e72c 00000000 S kthreadd
root 3 2 0 0 c003fdc8 00000000 S ksoftirqd/0
root 4 2 0 0 c004b2c4 00000000 S events/0
root 5 2 0 0 c004b2c4 00000000 S khelper

...

root 32 1 63964 21732 c009b74c afd0b844 S zygote
media 33 1 17212 1368 ffffffff afd0b6fc S /system/bin/mediaserver
root 34 1 812 240 c02181f4 afd0b45c S /system/bin/installd
keystore 35 1 1796 280 c01b52b4 afd0c0cc S /system/bin/keystore
root 37 1 824 276 c00b8fec afd0c51c S /system/bin/qemud
shell 39 1 732 204 c0158eb0 afd0b45c S /system/bin/sh
root 40 1 3376 180 ffffffff 00008294 S /sbin/adbd
system 60 32 125208 31256 ffffffff afd0b6fc S system_server
app_12 112 32 76032 19472 ffffffff afd0c51c S jp.co.omronsoft.openwnn
radio 118 32 88352 20500 ffffffff afd0c51c S com.android.phone
system 121 32 76268 20780 ffffffff afd0c51c S com.android.systemui
app_1 123 32 79236 23488 ffffffff afd0c51c S com.android.launcher
app_5 180 32 76352 20236 ffffffff afd0c51c S android.process.acore
root 186 40 732 204 c003da38 afd0c3ac S /system/bin/sh
root 187 186 688 280 c009b74c afd0b844 S logcat
app_8 201 32 74148 18368 ffffffff afd0c51c S com.android.deskclock
app_3 216 32 85184 18344 ffffffff afd0c51c S com.android.mms
app_9 220 32 75120 18892 ffffffff afd0c51c S android.process.media
app_13 247 32 75608 19472 ffffffff afd0c51c S com.android.email
app_11 262 32 72816 16836 ffffffff afd0c51c S com.android.protips
app_20 274 32 73256 17272 ffffffff afd0c51c S com.android.music
app_26 282 32 73852 18080 ffffffff afd0c51c S com.android.quicksearchbox
root 292 40 732 328 c003da38 afd0c3ac S /system/bin/sh
root 294 292 888 328 00000000 afd0b45c R ps
com.android.xxxなどのアプリは全てPID 32のzygoteがforkしている。

zygoteプロセスはinit.rcから起動される。ソースは
/frameworks/base/cmds/app_process/app_main.cpp

app_main.cppのmain関数でcom.android.internal.os.ZygoteInitのstatic mainを実行する。

ZygoteInit
main()
registerZygoteSocket() // サーバー側socketを初期化

preloadClasses() // frameworkのクラスを予め読む
// Class.forName()を呼んで、戻り値は見ない

preloadResources() // Resourceを読む

runSelectLoopMode() // select()でsocketの書き込み待ち
// 書き込みがあると、ZygoteConnection.runOnce()へ

ZygoteConnection
runOnce() // 引数をチェックしたり、uidとか決める

Zygote
forkAndSpecialize() // libcore/dalvik/src/main/java/dalvik/system/Zygote.java
// native method呼ぶだけ

/dalvik/vm/native/dalvik_system_Zygote.c
forkAndSpecializeCommon() // ココでfork()してる!
preloadClasses()はLogcatに
INFO/Zygote(32): ...preloaded 1830 classes in 7118ms.
みたいなログを出すやつ。
予め全部クラスをロードしたプロセスを作っておき、Processクラスの要求でforkしている。
zygoteはアプリのための初期化済みプロセスで、forkするサーバを兼ねているようだ。

0 件のコメント:

コメントを投稿