DVM初期化——FindClass、システムクラスをロードする(一)
3717 ワード
Dalvik findClassの方面から見て、またJava種類をSystem ClassとSystem Classに分けることができます。System Classは、JavaのクラスとAndrioidのコアクラスを指すのが一般的です。それらの違いは、System Classは仮想マシンの初期化時にロードされるということです。AndroidのKernelはLinux Kernelに基づいているので、Androidは新しいプロセスを作る時、Zygoteという特殊なプロセスを設計してfork新しいプロセスを作りました。そしてこのdalvikは基本的にsystem classをロードしただけのdalvikです。その後、プログラムが実行されるにつれて、各仮想はお互いの違いがあります。各プロセスのクラスと他のリソースがロードされています。
AndroidのZygoteプロセスのbinファイルはsystem\bin\ap_です。processは、アプリにありますprocessプロセスのmain関数では、startVMの呼び出しに伴い、Dalvikの起動が示されています。startVMでは、propertyを通じてget()呼び出しは、初期ヒープのようなDalvikの基本的な構成情報を初期化し、最大利用可能なヒープの大きさは、JITをサポートしているか、どのモードのインタプリタを選択するかなどです。例えば、以下のコードは、インタプリタの選択である。
dvd Class Startupでは、最初のステップは、急いでクラスをロードするのではなく、HashMapテーブルを初期化して、仮想マシンによってロードされたクラスをすべて保存します。HashMapを作成したらgDVMに保存されます。gDVMはグローバル変数であり、そのタイプはDvmGlobalsであり、これはC++structタイプであり、メンバー変数はかなり多く、そこには既にロードされたクラスだけでなく、Dalvikのインスタンスも保存されています。
AndroidのZygoteプロセスのbinファイルはsystem\bin\ap_です。processは、アプリにありますprocessプロセスのmain関数では、startVMの呼び出しに伴い、Dalvikの起動が示されています。startVMでは、propertyを通じてget()呼び出しは、初期ヒープのようなDalvikの基本的な構成情報を初期化し、最大利用可能なヒープの大きさは、JITをサポートしているか、どのモードのインタプリタを選択するかなどです。例えば、以下のコードは、インタプリタの選択である。
property_get("dalvik.vm.execution-mode", propBuf, "");
if (strcmp(propBuf, "int:portable") == 0) {
executionMode = kEMIntPortable;
} else if (strcmp(propBuf, "int:fast") == 0) {
executionMode = kEMIntFast;
#if defined(WITH_JIT)
} else if (strcmp(propBuf, "int:jit") == 0) {
executionMode = kEMJitCompiler;
#endif
}
基本的な配置属性を設定すると、これらの属性を利用して、JNI_を通過します。CreateJavaVM()の呼び出しは仮想マシンを作成します。どうしてCreateJavaVMの前にJNI_を追加しますか?前縁は変なようです。jni関数ではないですよ。そして、dvimStartup()の呼び出しを経て、GCメモリ管理と一部のシステムクラスを初期化します。この部分のシステムクラスを初期化して、呼出しのはdvd Class Startupです。では、この部分のシステム類は何ですか?どうして単独で出しますか?dvd Class Startupでは、最初のステップは、急いでクラスをロードするのではなく、HashMapテーブルを初期化して、仮想マシンによってロードされたクラスをすべて保存します。HashMapを作成したらgDVMに保存されます。gDVMはグローバル変数であり、そのタイプはDvmGlobalsであり、これはC++structタイプであり、メンバー変数はかなり多く、そこには既にロードされたクラスだけでなく、Dalvikのインスタンスも保存されています。
struct DvmGlobals gDvm;
gDvm.loadedClasses =
dvmHashTableCreate(256, (HashFreeFunc) dvmFreeClassInnards);
次に、この部分のシステムクラスをロードするために、createInitial Class()を呼び出します。 /*
* Create the initial classes. These are the first objects constructed
* within the nascent VM.
*/
if (!createInitialClasses()) {
return false;
}
コードの実現から見れば、ここは二つの部分に分かれています。第一部分はJavaの中で最も神秘的なクラスクラスをロードするために、第二部分はJavaという言語を構築するための基礎タイプをロードしています。/*
* Create the initial class instances. These consist of the class
* Class and all of the classes representing primitive types.
*/
static bool createInitialClasses() {
/*
* Initialize the class Class. This has to be done specially, particularly
* because it is an instance of itself.
*/
// Class
ClassObject* clazz = (ClassObject*)
dvmMalloc(classObjectSize(CLASS_SFIELD_SLOTS), ALLOC_NON_MOVING);
if (clazz == NULL) {
return false;
}
DVM_OBJECT_INIT(clazz, clazz);
SET_CLASS_FLAG(clazz, ACC_PUBLIC | ACC_FINAL | CLASS_ISCLASS);
clazz->descriptor = "Ljava/lang/Class;";
gDvm.classJavaLangClass = clazz;
LOGVV("Constructed the class Class.");
/*
* Initialize the classes representing primitive types. These are
* instances of the class Class, but other than that they're fairly
* different from regular classes.
*/
//
bool ok = true;
ok &= createPrimitiveType(PRIM_VOID, &gDvm.typeVoid);
ok &= createPrimitiveType(PRIM_BOOLEAN, &gDvm.typeBoolean);
ok &= createPrimitiveType(PRIM_BYTE, &gDvm.typeByte);
ok &= createPrimitiveType(PRIM_SHORT, &gDvm.typeShort);
ok &= createPrimitiveType(PRIM_CHAR, &gDvm.typeChar);
ok &= createPrimitiveType(PRIM_INT, &gDvm.typeInt);
ok &= createPrimitiveType(PRIM_LONG, &gDvm.typeLong);
ok &= createPrimitiveType(PRIM_FLOAT, &gDvm.typeFloat);
ok &= createPrimitiveType(PRIM_DOUBLE, &gDvm.typeDouble);
return ok;
}