從Dalvik findClass方面看,又可把Java類分爲System Class與非System Class。System Class通常指的是Java的類庫和Andrioid的核心類。而它們的區別在於,System Class是由虛擬機初始化時候加載的。而由於Android的Kernel是基於Linux Kernel,Android在建立一個新的進程時,設計了Zygote這個特殊的進程來fork新的進程,由於fork的寫時複製特性,而每一次都是基於Zygote這個進程來fork的,所以,每個新的進程誕生不只擁有了一個本身的dalvik,並且這個dalvik基本上是一個只是加載了system class的dalvik。然後,隨着程序的運行,每一個虛擬纔有了彼此的不一樣,加載着各個進程的class及其餘資源。java
Android的Zygote進程的bin檔就是system\bin\app_process,在app_process進程的main()函數中,隨着startVM()的調用,就標示着Dalvik的啓動。在startVM()中,經過property_get()調用,初始化Dalvik的基本配置信息,如初始堆,最大可用堆的大小,是否支持JIT,選擇什麼模式的解釋器等。例如如下代碼就是對解釋器的選擇。app
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函數啊。而而後通過dvmStartup()的調用,會初始化GC內存管理及一部分系統類。初始化這部分系統類,調用的是dvmClassStartup()。那麼,這部分系統類是什麼呢,爲何要單獨放出來呢?
函數
在dvmClassStartup()中,第一步並非急着去加載類,而是初始化一個HashMap表,用以保存全部被該虛擬機所加載的類。HashMap建立好以後就會被保存在gDVM中。gDVM是一個全局變量,它的類型是DvmGlobals,這是個C++ struct類型,成員變量至關的多,其中不只保存着已加載的類,還保存着Dalvik實例。
設計
struct DvmGlobals gDvm; gDvm.loadedClasses = dvmHashTableCreate(256, (HashFreeFunc) dvmFreeClassInnards);
接下來,就是調用createInitialClasses()來加載這部分系統類了。code
/* * Create the initial classes. These are the first objects constructed * within the nascent VM. */ if (!createInitialClasses()) { return false; }
從代碼的實現來看,這裏分爲兩部分工做,第一部分爲加載Java中最爲神祕的類Class,第二部分就是加載了用於構造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; }