2011年8月16日火曜日

Zygoteの簡単な説明

Androidではアプリケーションや多くのその他のプログラムはJavaで記述されています。これらのプログラムはDalvikVMの上で動きます。
それらのJavaのプログラムを起動するたびにDalvikVMを起動するのではなく、Zygoteと呼ばれるDalvikVMの大元のプロセスに要求を出すと、そのプロセスがforkシステムコールを使って自分自身のコピーの子プロセスを生成し、その子プロセスで指定されたJavaのプログラムを実行するようになっています。
Zygoteは通常必要となる全てのダイナミックリンクライブラリとJavaのクラスライブラリをロードした状態で待機しています。子プロセスはそれをコピーした状態から開始されるので起動にかかる時間を短縮することができます。また、書き込みを行っていないメモリページは複数のプロセスで共有されることになるので、たくさんのJavaのプログラムが同時に動いているときでも実際のメモリの使用量を少なくおさえることができます。Linuxの仮想メモリのしくみを上手に使っています。
Androidの中にあるJavaプログラムを実行する3つのコマンド
今回は軽い紹介だけですが、そのうちソースコードを探検したいと思います。
/system/bin/app_process
常駐するZygoteプロセスの実体ですが、引数にクラス名を指定して起動することもできます。
/system/bin/am コマンドを使うとコマンドラインからintentを発行してアプリケーションを起動することもできますが、その中で使われているのがapp_processです。amコマンドは以下のようなshellスクリプトです。
# Script to start "am" on the device, which has a very rudimentary
# shell.
#
base=/system
export CLASSPATH=$base/framework/am.jar
exec app_process $base/bin com.android.commands.am.Am "$@"


このコマンドのソースコードは
frameworks/base/cmds/app_process/app_main.cpp
/system/bin/dalvikvm
普通のjavaコマンドに近いコマンドラインオプションを受け付けます。(dalvik -h
でヘルプが出ます。)既存のJavaのプログラムを移植して使うのに便利です。例えば
JRubyをAndroidで動かしたい
JRubyをAndroidで動かしてみた
このコマンドのソースコードは
dalvik/dalvikvm/Main.c
JNIのInvocation APIを使ってJavaVMを生成しています。
/system/bin/dvz
上記の2つは実行するたびに新たにDalvikVMを起動しますが、dvzコマンドではZygoteプロセスにコマンドを送ってforkさせ、その子プロセスで指定したJavaプログラムを動かします。このため起動時間やメモリ効率の点で有利です。
このコマンドでやっていることを真似れば、自分で作ったネイティブのプログラムからJavaのプログラムを起動することもできると思います。
このコマンドのソースコードは
dalvik/dvz/dvz.c

0 件のコメント:

コメントを投稿