100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 深入理解ART虚拟机—虚拟机的启动

深入理解ART虚拟机—虚拟机的启动

时间:2021-04-06 10:57:46

相关推荐

深入理解ART虚拟机—虚拟机的启动

看art虚拟机也有一段时间了,是时候写点什么出来了。早先看art的时候,发现不是太能理解,所以就恶补了一下dalvik虚拟机,所以有了之前的dalvik系列,等再次回头看art的时候,确实轻松了不少。

art从Android L开始正式替换dalvik,成为Android的默认虚拟机,网上很多分析ART的文章都是基于KK的art源码,L的art源码和之前KK的差别比较大,L开始art才走向成熟,我们的分析则是基于L上的art。art的运行方式是AOT(Ahead Of Time),AOT和JIT(Just In Time)对应,JIT是即时编译,而AOT是提前编译,在apk安装的时候,由dex2oat将dex编译成oat文件。oat是扩展的elf文件,elf的文件结构不在这里详述,我几年前的文章《linker and loader 读书笔记》里有介绍。oat文件包含了类的各个method的native代码,会在apk运行时被加载。

我们来看art是怎么工作的:《深入理解Dalvik虚拟机- Android进程启动过程》这篇文章介绍了Android的进程启动过程,不管是art还是dalvik,apk的启动过程都是一样的,不一样的是JavaVM和JNIEnv的创建的代码实现不同。JavaVM和JNIEnv这两个是Java虚拟机的核心接口,art和dalvik有其各自不同的实现。

#if defined(__cplusplus)typedef _JNIEnv JNIEnv;typedef _JavaVM JavaVM;#elsetypedef const struct JNINativeInterface* JNIEnv;typedef const struct JNIInvokeInterface* JavaVM;#endifstruct JNIInvokeInterface {void* reserved0;void* reserved1;void* reserved2;jint (*DestroyJavaVM)(JavaVM*);jint (*AttachCurrentThread)(JavaVM*, JNIEnv**, void*);jint (*DetachCurrentThread)(JavaVM*);jint (*GetEnv)(JavaVM*, void**, jint);jint (*AttachCurrentThreadAsDaemon)(JavaVM*, JNIEnv**, void*);};struct _JavaVM {const struct JNIInvokeInterface* functions;#if defined(__cplusplus)jint DestroyJavaVM(){ return functions->DestroyJavaVM(this); }jint AttachCurrentThread(JNIEnv** p_env, void* thr_args){ return functions->AttachCurrentThread(this, p_env, thr_args); }jint DetachCurrentThread(){ return functions->DetachCurrentThread(this); }jint GetEnv(void** env, jint version){ return functions->GetEnv(this, env, version); }jint AttachCurrentThreadAsDaemon(JNIEnv** p_env, void* thr_args){ return functions->AttachCurrentThreadAsDaemon(this, p_env, thr_args); }#endif /*__cplusplus*/};

可见JavaVM的主要接口如下:

AttachCurrentThread — 将当前的Thread attach到JavaVM,主要是生成JniEnv对象,JniEnv对象是属于线程的,不同的线程有自己的JniEnv。JavaVM创建的时候,会在当前线程自动attach作为Java的主线程,Java->Native的JNI调用就是走这个线程,而如果你想在自己的pthread里调用Java的代码的话,就需要调用AttachCurrentThread,得到JniEnv才能执行Java代码。

DetachCurrentThread — Detach当前线程,销毁JniEnv。

GetEnv — 获得当前线程的JNIEnv,JNI是线程相关的,只有Attach过的线程,才有JniEnv对象。

DestoryJavaVM — 销毁JavaVM。

JavaVM是全局的,而JNIEnv是线程相关的,JNIEnv定义了所有的JNI调用的接口:

struct JNINativeInterface {void* reserved0;void* reserved1;void* reserved2;void* reserved3;jint (*GetVersion)(JNIEnv *);jclass(*DefineClass)(JNIEnv*, const char*, jobject, const jbyte*,jsize);jclass(*FindClass)(JNIEnv*, const char*);jmethodID (*FromReflectedMethod)(JNIEnv*, jobject);jfieldID (*FromReflectedField)(JNIEnv*, jobject);/* spec doesn show jboolean parameter */jobject(*ToReflectedMethod)(JNIEnv*, jclass, jmethodID, jboolean);jclass(*GetSuperclass)(JNIEnv*, jclass);jboolean (*IsAssignableFrom)(JNIEnv*, jclass, jclass);/* spec doesn show jboolean parameter */jobject(*ToReflectedField)(JNIEnv*, jclass, jfieldID, jboolean);jint (*Throw)(JNIEnv*, jthrowable);jint (*ThrowNew)(JNIEnv *, jclass, const char *);jthrowable (*ExceptionOccurred)(JNIEnv*);void (*ExceptionDescribe)(JNIEnv*);void (*ExceptionClear)(JNIEnv*);void (*FatalError)(JNIEnv*, const char*);jint (*PushLocalFrame)(JNIEnv*, jint);jobject(*PopLocalFrame)(JNIEnv*, jobject);jobject(*NewGlobalRef)(JNIEnv*, jobject);void (*DeleteGlobalRef)(JNIEnv*, jobject);void (*DeleteLocalRef)(JNIEnv*, jobject);jboolean (*IsSameObject)(JNIEnv*, jobject, jobject);jobject(*NewLocalRef)(JNIEnv*, jobject);jint (*EnsureLocalCapacity)(JNIEnv*, jint);jobject(*AllocObject)(JNIEnv*, jclass);jobject(*NewObject)(JNIEnv*, jclass, jmethodID, ...);jobject(*NewObjectV)(JNIEnv*, jclass, jmethodID, va_list);jobject(*NewObjectA)(JNIEnv*, jclass, jmethodID, jvalue*);jclass(*GetObjectClass)(JNIEnv*, jobject);jboolean (*IsInstanceOf)(JNIEnv*, jobject, jclass);jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);jobject(*CallObjectMethod)(JNIEnv*, jobject, jmethodID, ...);jobject(*CallObjectMethodV)(JNIEnv*, jobject, jmethodID, va_list);jobject(*CallObjectMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);jboolean (*CallBooleanMethod)(JNIEnv*, jobject, jmethodID, ...);jboolean (*CallBooleanMethodV)(JNIEnv*, jobject, jmethodID, va_list);jboolean (*CallBooleanMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);jbyte (*CallByteMethod)(JNIEnv*, jobject, jmethodID, ...);jbyte (*CallByteMethodV)(JNIEnv*, jobject, jmethodID, va_list);jbyte (*CallByteMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);jchar (*CallCharMethod)(JNIEnv*, jobject, jmethodID, ...);jchar (*CallCharMethodV)(JNIEnv*, jobject, jmethodID, va_list);jchar (*CallCharMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);jshort(*CallShortMethod)(JNIEnv*, jobject, jmethodID, ...);jshort(*CallShortMethodV)(JNIEnv*, jobject, jmethodID, va_list);jshort(*CallShortMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);jint (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...);jint (*CallIntMethodV)(JNIEnv*, jobject, jmethodID, va_list);jint (*CallIntMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);jlong (*CallLongMethod)(JNIEnv*, jobject, jmethodID, ...);jlong (*CallLongMethodV)(JNIEnv*, jobject, jmethodID, va_list);jlong (*CallLongMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);jfloat(*CallFloatMethod)(JNIEnv*, jobject, jmethodID, ...);jfloat(*CallFloatMethodV)(JNIEnv*, jobject, jmethodID, va_list);jfloat(*CallFloatMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);jdouble(*CallDoubleMethod)(JNIEnv*, jobject, jmethodID, ...);jdouble(*CallDoubleMethodV)(JNIEnv*, jobject, jmethodID, va_list);jdouble(*CallDoubleMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);void (*CallVoidMethodV)(JNIEnv*, jobject, jmethodID, va_list);void (*CallVoidMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);jobject(*CallNonvirtualObjectMethod)(JNIEnv*, jobject, jclass,jmethodID, ...);jobject(*CallNonvirtualObjectMethodV)(JNIEnv*, jobject, jclass,jmethodID, va_list);jobject(*CallNonvirtualObjectMethodA)(JNIEnv*, jobject, jclass,jmethodID, jvalue*);jboolean (*CallNonvirtualBooleanMethod)(JNIEnv*, jobject, jclass,jmethodID, ...);jboolean (*CallNonvirtualBooleanMethodV)(JNIEnv*, jobject, jclass,jmethodID, va_list);jboolean (*CallNonvirtualBooleanMethodA)(JNIEnv*, jobject, jclass,jmethodID, jvalue*);jbyte (*CallNonvirtualByteMethod)(JNIEnv*, jobject, jclass,jmethodID, ...);jbyte (*CallNonvirtualByteMethodV)(JNIEnv*, jobject, jclass,jmethodID, va_list);jbyte (*CallNonvirtualByteMethodA)(JNIEnv*, jobject, jclass,jmethodID, jvalue*);jchar (*CallNonvirtualCharMethod)(JNIEnv*, jobject, jclass,jmethodID, ...);jchar (*CallNonvirtualCharMethodV)(JNIEnv*, jobject, jclass,jmethodID, va_list);jchar (*CallNonvirtualCharMethodA)(JNIEnv*, jobject, jclass,jmethodID, jvalue*);jshort(*CallNonvirtualShortMethod)(JNIEnv*, jobject, jclass,jmethodID, ...);jshort(*CallNonvirtualShortMethodV)(JNIEnv*, jobject, jclass,jmethodID, va_list);jshort(*CallNonvirtualShortMethodA)(JNIEnv*, jobject, jclass,jmethodID, jvalue*);jint (*CallNonvirtualIntMethod)(JNIEnv*, jobject, jclass,jmethodID, ...);jint (*CallNonvirtualIntMethodV)(JNIEnv*, jobject, jclass,jmethodID, va_list);jint (*CallNonvirtualIntMethodA)(JNIEnv*, jobject, jclass,jmethodID, jvalue*);jlong (*CallNonvirtualLongMethod)(JNIEnv*, jobject, jclass,jmethodID, ...);jlong (*CallNonvirtualLongMethodV)(JNIEnv*, jobject, jclass,jmethodID, va_list);jlong (*CallNonvirtualLongMethodA)(JNIEnv*, jobject, jclass,jmethodID, jvalue*);jfloat(*CallNonvirtualFloatMethod)(JNIEnv*, jobject, jclass,jmethodID, ...);jfloat(*CallNonvirtualFloatMethodV)(JNIEnv*, jobject, jclass,jmethodID, va_list);jfloat(*CallNonvirtualFloatMethodA)(JNIEnv*, jobject, jclass,jmethodID, jvalue*);jdouble(*CallNonvirtualDoubleMethod)(JNIEnv*, jobject, jclass,jmethodID, ...);jdouble(*CallNonvirtualDoubleMethodV)(JNIEnv*, jobject, jclass,jmethodID, va_list);jdouble(*CallNonvirtualDoubleMethodA)(JNIEnv*, jobject, jclass,jmethodID, jvalue*);void (*CallNonvirtualVoidMethod)(JNIEnv*, jobject, jclass,jmethodID, ...);void (*CallNonvirtualVoidMethodV)(JNIEnv*, jobject, jclass,jmethodID, va_list);void (*CallNonvirtualVoidMethodA)(JNIEnv*, jobject, jclass,jmethodID, jvalue*);jfieldID (*GetFieldID)(JNIEnv*, jclass, const char*, const char*);jobject(*GetObjectField)(JNIEnv*, jobject, jfieldID);jboolean (*GetBooleanField)(JNIEnv*, jobject, jfieldID);jbyte (*GetByteField)(JNIEnv*, jobject, jfieldID);jchar (*GetCharField)(JNIEnv*, jobject, jfieldID);jshort(*GetShortField)(JNIEnv*, jobject, jfieldID);jint (*GetIntField)(JNIEnv*, jobject, jfieldID);jlong (*GetLongField)(JNIEnv*, jobject, jfieldID);jfloat(*GetFloatField)(JNIEnv*, jobject, jfieldID);jdouble(*GetDoubleField)(JNIEnv*, jobject, jfieldID);void (*SetObjectField)(JNIEnv*, jobject, jfieldID, jobject);void (*SetBooleanField)(JNIEnv*, jobject, jfieldID, jboolean);void (*SetByteField)(JNIEnv*, jobject, jfieldID, jbyte);void (*SetCharField)(JNIEnv*, jobject, jfieldID, jchar);void (*SetShortField)(JNIEnv*, jobject, jfieldID, jshort);void (*SetIntField)(JNIEnv*, jobject, jfieldID, jint);void (*SetLongField)(JNIEnv*, jobject, jfieldID, jlong);void (*SetFloatField)(JNIEnv*, jobject, jfieldID, jfloat);void (*SetDoubleField)(JNIEnv*, jobject, jfieldID, jdouble);jmethodID (*GetStaticMethodID)(JNIEnv*, jclass, const char*, const char*);jobject(*CallStaticObjectMethod)(JNIEnv*, jclass, jmethodID, ...);jobject(*CallStaticObjectMethodV)(JNIEnv*, jclass, jmethodID, va_list);jobject(*CallStaticObjectMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);jboolean (*CallStaticBooleanMethod)(JNIEnv*, jclass, jmethodID, ...);jboolean (*CallStaticBooleanMethodV)(JNIEnv*, jclass, jmethodID,va_list);jboolean (*CallStaticBooleanMethodA)(JNIEnv*, jclass, jmethodID,jvalue*);jbyte (*CallStaticByteMethod)(JNIEnv*, jclass, jmethodID, ...);jbyte (*CallStaticByteMethodV)(JNIEnv*, jclass, jmethodID, va_list);jbyte (*CallStaticByteMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);jchar (*CallStaticCharMethod)(JNIEnv*, jclass, jmethodID, ...);jchar (*CallStaticCharMethodV)(JNIEnv*, jclass, jmethodID, va_list);jchar (*CallStaticCharMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);jshort(*CallStaticShortMethod)(JNIEnv*, jclass, jmethodID, ...);jshort(*CallStaticShortMethodV)(JNIEnv*, jclass, jmethodID, va_list);jshort(*CallStaticShortMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);jint (*CallStaticIntMethod)(JNIEnv*, jclass, jmethodID, ...);jint (*CallStaticIntMethodV)(JNIEnv*, jclass, jmethodID, va_list);jint (*CallStaticIntMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);jlong (*CallStaticLongMethod)(JNIEnv*, jclass, jmethodID, ...);jlong (*CallStaticLongMethodV)(JNIEnv*, jclass, jmethodID, va_list);jlong (*CallStaticLongMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);jfloat(*CallStaticFloatMethod)(JNIEnv*, jclass, jmethodID, ...);jfloat(*CallStaticFloatMethodV)(JNIEnv*, jclass, jmethodID, va_list);jfloat(*CallStaticFloatMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);jdouble(*CallStaticDoubleMethod)(JNIEnv*, jclass, jmethodID, ...);jdouble(*CallStaticDoubleMethodV)(JNIEnv*, jclass, jmethodID, va_list);jdouble(*CallStaticDoubleMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);void (*CallStaticVoidMethod)(JNIEnv*, jclass, jmethodID, ...);void (*CallStaticVoidMethodV)(JNIEnv*, jclass, jmethodID, va_list);void (*CallStaticVoidMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);jfieldID (*GetStaticFieldID)(JNIEnv*, jclass, const char*,const char*);jobject(*GetStaticObjectField)(JNIEnv*, jclass, jfieldID);jboolean (*GetStaticBooleanField)(JNIEnv*, jclass, jfieldID);jbyte (*GetStaticByteField)(JNIEnv*, jclass, jfieldID);jchar (*GetStaticCharField)(JNIEnv*, jclass, jfieldID);jshort(*GetStaticShortField)(JNIEnv*, jclass, jfieldID);jint (*GetStaticIntField)(JNIEnv*, jclass, jfieldID);jlong (*GetStaticLongField)(JNIEnv*, jclass, jfieldID);jfloat(*GetStaticFloatField)(JNIEnv*, jclass, jfieldID);jdouble(*GetStaticDoubleField)(JNIEnv*, jclass, jfieldID);void (*SetStaticObjectField)(JNIEnv*, jclass, jfieldID, jobject);void (*SetStaticBooleanField)(JNIEnv*, jclass, jfieldID, jboolean);void (*SetStaticByteField)(JNIEnv*, jclass, jfieldID, jbyte);void (*SetStaticCharField)(JNIEnv*, jclass, jfieldID, jchar);void (*SetStaticShortField)(JNIEnv*, jclass, jfieldID, jshort);void (*SetStaticIntField)(JNIEnv*, jclass, jfieldID, jint);void (*SetStaticLongField)(JNIEnv*, jclass, jfieldID, jlong);void (*SetStaticFloatField)(JNIEnv*, jclass, jfieldID, jfloat);void (*SetStaticDoubleField)(JNIEnv*, jclass, jfieldID, jdouble);jstring(*NewString)(JNIEnv*, const jchar*, jsize);jsize (*GetStringLength)(JNIEnv*, jstring);const jchar* (*GetStringChars)(JNIEnv*, jstring, jboolean*);void (*ReleaseStringChars)(JNIEnv*, jstring, const jchar*);jstring(*NewStringUTF)(JNIEnv*, const char*);jsize (*GetStringUTFLength)(JNIEnv*, jstring);/* JNI spec says this returns const jbyte*, but thats inconsistent */const char* (*GetStringUTFChars)(JNIEnv*, jstring, jboolean*);void (*ReleaseStringUTFChars)(JNIEnv*, jstring, const char*);jsize (*GetArrayLength)(JNIEnv*, jarray);jobjectArray (*NewObjectArray)(JNIEnv*, jsize, jclass, jobject);jobject(*GetObjectArrayElement)(JNIEnv*, jobjectArray, jsize);void (*SetObjectArrayElement)(JNIEnv*, jobjectArray, jsize, jobject);jbooleanArray (*NewBooleanArray)(JNIEnv*, jsize);jbyteArray (*NewByteArray)(JNIEnv*, jsize);jcharArray (*NewCharArray)(JNIEnv*, jsize);jshortArray (*NewShortArray)(JNIEnv*, jsize);jintArray(*NewIntArray)(JNIEnv*, jsize);jlongArray (*NewLongArray)(JNIEnv*, jsize);jfloatArray (*NewFloatArray)(JNIEnv*, jsize);jdoubleArray (*NewDoubleArray)(JNIEnv*, jsize);jboolean* (*GetBooleanArrayElements)(JNIEnv*, jbooleanArray, jboolean*);jbyte*(*GetByteArrayElements)(JNIEnv*, jbyteArray, jboolean*);jchar*(*GetCharArrayElements)(JNIEnv*, jcharArray, jboolean*);jshort*(*GetShortArrayElements)(JNIEnv*, jshortArray, jboolean*);jint* (*GetIntArrayElements)(JNIEnv*, jintArray, jboolean*);jlong*(*GetLongArrayElements)(JNIEnv*, jlongArray, jboolean*);jfloat*(*GetFloatArrayElements)(JNIEnv*, jfloatArray, jboolean*);jdouble* (*GetDoubleArrayElements)(JNIEnv*, jdoubleArray, jboolean*);void (*ReleaseBooleanArrayElements)(JNIEnv*, jbooleanArray,jboolean*, jint);void (*ReleaseByteArrayElements)(JNIEnv*, jbyteArray,jbyte*, jint);void (*ReleaseCharArrayElements)(JNIEnv*, jcharArray,jchar*, jint);void (*ReleaseShortArrayElements)(JNIEnv*, jshortArray,jshort*, jint);void (*ReleaseIntArrayElements)(JNIEnv*, jintArray,jint*, jint);void (*ReleaseLongArrayElements)(JNIEnv*, jlongArray,jlong*, jint);void (*ReleaseFloatArrayElements)(JNIEnv*, jfloatArray,jfloat*, jint);void (*ReleaseDoubleArrayElements)(JNIEnv*, jdoubleArray,jdouble*, jint);void (*GetBooleanArrayRegion)(JNIEnv*, jbooleanArray,jsize, jsize, jboolean*);void (*GetByteArrayRegion)(JNIEnv*, jbyteArray,jsize, jsize, jbyte*);void (*GetCharArrayRegion)(JNIEnv*, jcharArray,jsize, jsize, jchar*);void (*GetShortArrayRe

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。