Android P zygote原理分析のapp_process

5626 ワード

Androidシステムのカーネルの初期化が完了した後、ユーザー空間に入って起動する最初のプロセスはinitと呼ばれています.彼はAndroidシステムのすべてのプロセスの祖先です.このプロセスが起動するとファイルシステムを初期化し、多くの子供を育てます.例えば、システムの中に多くのサービスがあります.その中にzygoteというサービスがあります.zygoteは翻訳すると受精卵と呼ばれています.それはinitのすべての子供の中で比較的に特殊な1つであるべきで、他の子供はどれだけ大きいかはいくつかの下層サービスで、zygoteという子供の特殊なところはjava仮想機を起動して、androidをjavaの世界に持ち込んで、それからandroidは異なっていて、これもandroidが技術的に他の多くのlinuxシステムとの主要な違いの1つだと思います!
zygoteはandroidにおいて重要な役割を果たしているが、いったい何の役に立つのだろうか.
1.java仮想マシンの起動を担当する
2.プリロードが必要なクラスを多数ロード
3.システムサーバの起動を担当し、システムサーバはandroidのすべてのサービスを起動し、基本的に上位フレームワークのすべての機能を完了します.
4.新しいプロセスの初期化を担当します.実はfork javaの独立したプロセスです.例えばactを起動すると、zygoteは新しいactのためにプロセスを確立し、actのmainを呼び出したり、OnCreateを呼び出したりします.そうすれば、理解しやすいかもしれません.
しかしinitにとってzygoteは実は普通のサービスで、彼が育てた他の子供と何の違いもありません.コードを参照:
service zygote /system/bin/app_process32 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
    class main
    priority -20
    user root
    group root readproc reserved_disk
    socket zygote stream 660 root system
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart audioserver
    onrestart restart cameraserver
    onrestart restart media
    onrestart restart netd
    onrestart restart wificond
    writepid /dev/cpuset/foreground/tasks

service zygote_secondary /system/bin/app_process64 -Xzygote /system/bin --zygote --socket-name=zygote_secondary
    class main
    priority -20
    user root
    group root readproc reserved_disk
    socket zygote_secondary stream 660 root system
    onrestart restart zygote
    writepid /dev/cpuset/foreground/tasks

プロセッサプラットフォームにとって32ビットと64ビットの差があるため、私たちの手にある携帯電話にもこの差があり、すべてのzygoteにもこの差があります.実は32,64,32に分かれています.64,64_32、この4つのモードは、ある日128512モードになるかもしれません.以上のコードは32_です64ビットモード、メインモード32ビット、アシストモード64ビット、実はこの携帯電話は64ビットですが、彼は32ビットをサポートしています.この設定は多くのアプリケーションを32モードで実行しますが、特殊な要求を持つアプリケーションも64ビットモードで実行されます.これはzygote_が作成プロセスを担当します.secondary.
次にapp_を分析しますプロセス:
app_プロセスというプロセスはzygoteを起動するだけでなく、普通のクラスを起動することもできます.彼はあなたのパラメータによって異なる機能を実現します.
-Xzygoteこのパラメータは仮想マシンに渡され、app_に渡されません.プロセスは、新しいjvmを再初期化する必要があることを示します.
--zygote:このパラメータはappに渡されます.プロセスはzygoteモードを起動することを示す.
--start-system-server:このパラメータはsystemServerサービスの起動を示します.一般的に、このパラメータはzygoteモードのみで、他のモードにはこれが必要ないようです.
--socket-name=zygote:このパラメータはsocketの名前を表します.zygoteの起動が完了した後、終了することはありません.彼は他のアプリケーションのためにプロセスを作成する責任を負います.amsはこのsocketとzygoteの通信を通じてプロセスの作成を完了します.
--アプリケーション:これは実際には別のモードのフラグで、起動が一般的なアプリケーションであることを示しています.
--nice-name=これは作成されたプロセスの名前を表し、zygoteモードにはこれがありません.
-classpathまたは-cpという一般的なアプリケーションを作成する際のclassパスを推測します.
app_プロセスのmain関数は主に以上のパラメータに対する処理であり,それ以外は新規APPRuntimeクラスである.
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));

このクラスはjavaのmain classを起動する責任を負います
    if (zygote) {
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    } else {
        fprintf(stderr, "Error: no class name or --zygote supplied.
"); app_usage(); LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied."); }

zygoteモードの初期化を担当するのはZytoteInitクラス、他のプロセスの初期化を担当するのはRuntimeInitクラスです.
実际に分析を続けるなら、この二つの线に沿って、分析を続けることができます.后で奇迹が待っていると思います.
でも今日の任務はappを分析することですプロセス、别の未来に任せよう!
理解するならapp_プロセスがjvmをどのように起動し、java層をどのようにジャンプするかは、AppRuntimeを分析しないのは現実的ではなく、無駄なテーブルになると推定されています.今日の唯一の難易度の高いAppRuntimeを分析します
AppRuntimeはAndroid Runtimeを継承します.Android Runtimeには2つの虚関数があるため、AppRuntimeは主にこの2つの関数を実現します.

    /**
     * This gets called after the VM has been created, but before we
     * run any code. Override it to make any FindClass calls that need
     * to use CLASSPATH.
     */
    virtual void onVmCreated(JNIEnv* env);

    /**
     * This gets called after the JavaVM has initialized.  Override it
     * with the system's native entry point.
     */
    virtual void onStarted() = 0;
    /**
     * This gets called after the JavaVM has initialized after a Zygote
     * fork. Override it to initialize threads, etc. Upon return, the
     * correct static main will be invoked.
     */
    virtual void onZygoteInit() { }

    /**
     * Called when the Java application exits to perform additional cleanup actions
     * before the process is terminated.
     */
    virtual void onExit(int /*code*/) { }

名前から分かるように、1つは仮想マシンの作成後に呼び出され、1つは仮想マシンの起動後に呼び出されます.
AppRuntimeの場合、onVmCreatedの主な役割はメイン関数名を設定することであり、onStarted関数はイベントマネージャを起動し、main関数を呼び出すことです.
zygoteモードではonVmCreatedは無効です.
次に最も重要な関数を見てみましょうstart関数、この関数は主に以下のタスクを完了します.
1.jniの初期化
2.jvm仮想マシンの起動
3.無数のjni関数を登録する
4.javaクラスの起動
jniの初期化:
プライマリコールjni_invocation.Init初期化完了
  if (!FindSymbol(reinterpret_cast(&JNI_GetDefaultJavaVMInitArgs_),
                  "JNI_GetDefaultJavaVMInitArgs")) {
    return false;
  }
  if (!FindSymbol(reinterpret_cast(&JNI_CreateJavaVM_),
                  "JNI_CreateJavaVM")) {
    return false;
  }
  if (!FindSymbol(reinterpret_cast(&JNI_GetCreatedJavaVMs_),
                  "JNI_GetCreatedJavaVMs")) {
    return false;
  }

実は主にこれらのjni関数を変換して、これらのjni関数は仮想マシンを作成する時に呼び出されます
仮想マシンの作成には、主に無数のパラメータ処理が含まれ、最後にJNI_が呼び出されます.CreateJavaVMはjvmの作成を完了します.
jniの無数の上位javaが呼び出す必要があるjni関数を登録しますが、実はここでは各jni登録関数を呼び出す責任があります.システム初期化フェーズのすべてのjni関数が含まれていると推測します.
Javaクラスの静的main関数を呼び出す方法は一般的です.特に何もないようです.