从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及其他资源。
Android的Zygote进程的bin档就是system\bin\app_process,在app_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函数啊。而然后经过dvmStartup()的调用,会初始化GC内存管理及一部分系统类。初始化这部分系统类,调用的是dvmClassStartup()。那么,这部分系统类是什么呢,为什么要单独放出来呢?
在dvmClassStartup()中,第一步并不是急着去加载类,而是初始化一个HashMap表,用以保存所有被该虚拟机所加载的类。HashMap创建好之后就会被保存在gDVM中。gDVM是一个全局变量,它的类型是DvmGlobals,这是个C++ struct类型,成员变量相当的多,其中不仅保存着已加载的类,还保存着Dalvik实例。
struct DvmGlobals gDvm;
gDvm.loadedClasses =
dvmHashTableCreate(256, (HashFreeFunc) dvmFreeClassInnards);
接下来,就是调用createInitialClasses()来加载这部分系统类了。
/*
* 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;
}