Dalvik虚拟机总结
来源:互联网 发布:拍照软件萌 编辑:程序博客网 时间:2024/06/06 22:22
一、Dalvik虚拟机启动
在启动Zygote进程时,会启动Dalvik虚拟机,完成下面几件事:
1. 创建了一个Dalvik虚拟机实例;
2. 加载了Java核心类及注册其JNI方法;
3. 为主线程的设置了一个JNI环境;
4. 注册了Android核心类的JNI方法。
void AndroidRuntime::start(const char* className, const bool startSystemServer){ ...... /* start the virtual machine */ if (startVm(&mJavaVM, &env) != 0) goto bail; /* * Register android functions. */ if (startReg(env) < 0) { LOGE("Unable to register all android natives\n"); goto bail; } ...... /* * Start VM. This thread becomes the main thread of the VM, and will * not return until the VM exits. */ jclass startClass; jmethodID startMeth; slashClassName = strdup(className); for (cp = slashClassName; *cp != '\0'; cp++) if (*cp == '.') *cp = '/'; startClass = env->FindClass(slashClassName); if (startClass == NULL) { LOGE("JavaVM unable to locate class '%s'\n", slashClassName); /* keep going */ } else { startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V"); if (startMeth == NULL) { LOGE("JavaVM unable to find main() in '%s'\n", className); /* keep going */ } else { env->CallStaticVoidMethod(startClass, startMeth, strArray); ...... } } LOGD("Shutting down VM\n"); if (mJavaVM->DetachCurrentThread() != JNI_OK) LOGW("Warning: unable to detach main thread\n"); if (mJavaVM->DestroyJavaVM() != 0) LOGW("Warning: VM did not shut down cleanly\n"); ......}
二、第一次解释执行java程序,env->CallStaticVoidMethod(startClass, startMeth, strArray)最终会解释执行com.android.internal.os.ZygoteInit类的静态成员函数main
参考Dalvik虚拟机的运行过程分析,随着方法调用的不同,不断执行不同的GOTO_TARGET(invokeMethod, bool methodCallRange, const Method* _methodToCall, u2 count, u2 regs)或者GOTO_TARGET(returnFromMethod)等等,去解释执行java程序。
三、Zygote进程等待来在SystemServer的请求,来创建应用程序进程
static native int selectReadable(FileDescriptor[] fds) throws IOException;
此时dalvik虚拟机不是解释执行java程序,而是调用C/C++程序的入口地址,直接执行C/C++代码。由于在第一步中已经注册Android核心JNI,所以可以直接调用,请看考下面的第六点。
四、Zygote进程创建SystemServer进程
pid = Zygote.forkSystemServer( parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, debugFlags, null, parsedArgs.permittedCapabilities, parsedArgs.effectiveCapabilities);
if (pid == 0) { handleSystemServerProcess(parsedArgs);//执行了com.android.server.SystemServer中main方法 }本质上使用fork来创建一个新的进程,Zygote进程在启动是创建的Dalvik虚拟机实例和主线程的环境,使用COW的方式共享。其他两点由于是只读,共享即可。
返回到pid==0,此时已经是SystemServer进程的Davlik虚拟机主线程的环境来解释执行handleSystemServerProcess。
五、SystemServer进程调用Process.start,通过Socket请求Zygote进程来创建应用程序进程
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, rlimits);
if (pid == 0) { // in child handleChildProc(parsedArgs, descriptors, newStderr);//android.app.ActivityThread中的main函数 // should never happen return true; }和第四点的描述一样。
六、应用程序进程注册JNI,并执行JNI方法。
注册过程请参考Dalvik虚拟机JNI方法的注册过程分析,会调用JNI_OnLoad获取主线程的Dalvik虚拟机环境JNIENV,并调用了dvmSetNativeFunc设置了navtiveFunc。
当执行到JNI方法时,会调用*method->nativeFunc,不是解释执行,是直接在机器上执行。
void dvmCallMethodV(Thread* self, const Method* method, Object* obj, bool fromJni, JValue* pResult, va_list args){ ...... if (dvmIsNativeMethod(method)) { TRACE_METHOD_ENTER(self, method); /* * Because we leave no space for local variables, "curFrame" points * directly at the method arguments. */ (*method->nativeFunc)(self->curFrame, pResult, method, self); TRACE_METHOD_EXIT(self, method); } else { dvmInterpret(self, method, pResult); } ......}当如果想在JNI方法中调用Java方法,必须得有当前线程的Davlik虚拟机环境JNIENV,例如:
(*jniEnv)->CallVoidMethod(jniEnv, mTestProvider, sayHello,jstrMSG);和第二点一样,必须由Davlik虚拟机去解释执行Java方法。
七、应用程序进程,Java中开启一个线程,Thread.start
参考Dalvik虚拟机进程和线程的创建过程分析,使用clone创建了一个新的线程,和进程(主线程)共享进程空间,由于此线程没有Dalvik虚拟机环境JNIENV,所以要为该进程设置虚拟机环境。有了环境后就可以在解释执行Java代码了,如下:
dvmCallMethod(self, run, self->threadObj, &unused);
八、应用程序进程,C/C++中开启一个线程
1、.只执行C/C++代码的Native线程的创建过程:
不会创建该线程的Dalvik虚拟机环境JNIENV。
2、能同时执行C/C++代码和Java代码的Native线程的创建过程
需要创建该线程的Dalvik虚拟机环境JNIENV,就可以解释执行Java代码了。
- Dalvik虚拟机总结
- Android 虚拟机学习总结Dalvik虚拟机介绍
- Dalvik虚拟机
- Dalvik虚拟机
- Dalvik虚拟机
- Dalvik虚拟机
- dalvik 虚拟机
- Dalvik 虚拟机
- Dalvik虚拟机
- Dalvik 虚拟机
- Dalvik虚拟机
- Dalvik虚拟机
- Dalvik虚拟机
- Dalvik虚拟机
- Dalvik虚拟机
- Dalvik虚拟机
- Dalvik虚拟机
- Dalvik虚拟机
- Welcome to the Windows Bridge for iOS project preview
- 【HDU4722】【Good Numbers】
- 欢迎使用CSDN-markdown编辑器
- 浅谈"壳"(一)
- Servlet+JSP+JavaBean开发模式(MVC)介绍
- Dalvik虚拟机总结
- shared_ptr/unique_ptr一点体会
- Kinect2.0+EmguCV获取景深图
- Caffe源码(二):blob 分析
- 卫星式菜单
- HDU 3732(Ahui Writes Word)多重背包
- iOS Date Picker控件的简单使用(点击一个input框,弹出)
- EM算法
- 插件启动顺序控制