Zygote プロセスについて

Zygote は Android オペレーティング システムのプロセスで、同じアプリケーション バイナリ インターフェース(ABI)のすべてのシステムとアプリのプロセスの起点として機能します。

Google Pixel 7 以降などの最新のデバイスでは、64 ビット Zygote プロセスとなっています。さらに、プライマリ ABI 向けの WebView Zygote もあり、これは WebView を実行するプロセスに固有のライブラリとリソースが含まれる、専用の Zygote です。

Zygote は次のタスクを実行します。

  1. Android OS が初期化されると、init デーモンが Zygote プロセスを生成します。一部のデュアル アーキテクチャ システムでは、2 つの Zygote プロセス(64 ビットと 32 ビット)が生成されます。このページでは単一のアーキテクチャ システムのみについて説明します。

  2. Zygote は即座に未特化アプリプロセス(USAP)を生成することも、アプリがプロセスを必要とするまで待機してからプロセスを生成することもできます。最初のオプションはシステム プロパティまたは Android Debug Bridge コマンドから有効にする必要があります。プロセスを即座に生成するよう Zygote を設定する方法について詳細は、未特化アプリプロセス プールを有効にするをご覧ください。

    • USAP プールがデバイスで有効な場合:

      1. システム サーバーは UNIX ドメインのソケットを使用して、プールの利用可能な USAP に接続します。システム サーバーはプロセス ID(PID)、CGroup、その他の情報を変更して、アプリ用途に USAP を事前設定するようリクエストします。
      2. USAP の事前設定が完了すると、システム サーバーに PID が返されます。
      3. アプリがこの USAP の 1 つを占有すると、その USAP はプールに含まれなくなります。プール内の USAP が 1 つ以下になると、Zygote は新しい USAP をプールに補充します。
    • Zygote が遅延評価を使用してプロセスを生成する場合:

      1. システム サーバーでアプリがプロセスを必要としていることを示すコマンドを受信します。
      2. システム サーバーは UNIX ドメインのソケットを使用して、コマンドを適切な Zygote に送信します。
      3. Zygote はプロセスをフォークして、PID、CGroup、その他の情報を変更します。
      4. プロセスが完了すると、Zygote に PID が返され、そこからシステム サーバーに渡されます。

USAP プールを有効にする

USAP プールの使用を有効化するには、次のいずれかを実行します。

  • /build/make/target/product/runtime_libart.mkdalvik.vm.usap_pool_enabled システム プロパティを true に設定します。

  • 次のコマンドを実行します。

    adb shell am broadcast -a \"com.google.android.gms.phenotype.FLAG_OVERRIDE\" --es package \"com.google.android.platform.runtime_native\" --es user \"\*\" --esa flags \"usap_pool_enabled\" --esa values \"true\" --esa types \"string\" com.google.android.gms
    

この機能が有効な場合、それぞれの Zygote はフォークされたプロセスのプールを保持します。このプロセスはアプリ起動プロセスの中でアプリに依存しない部分を実行します。

Zygote に関する問題のトラブルシューティング

このセクションでは Zygote に関連する問題のソリューションを説明します。

Zygote がクラッシュする

デバイスが適切に再起動せず、ログまたはクラッシュ レポートで Zygote の問題の発生が示されている場合、通常 initd またはシステム サーバーのクラッシュを引き起こす変更を最近行ったことが原因です。コードを修正すると問題も解決されます。

SELinux 拒否または IO 障害

Zygote はプロセスの境界全体でのファイル記述子の健全性に厳格です。ファイル記述子がフォークの際に存在していても、許可リストに含まれない場合は、/dev/null への dup システムコールを使用して、キャッシュに保存されたファイル記述子が新しく開かれたファイルへのアクセスに意図せず使用されないようにします。

リソースを Zygote に読み込,む変更をフレームワークに加えていて、SELinux 拒否または IO 障害が発生している場合は、次をお試しください。

  • 名前未設定のファイル記述子の場合、Restat が呼び出されたときに fds_to_ignore ベクトルにファイル記述子を含めます。

  • 名前設定済みのファイル記述子の場合:

    1. WORKING_DIRECTORY/frameworks/base/core/jni/fd_utils.cpp を編集します。
    2. 開いているファイルの許可リストへのパスを追加します。