一、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虚拟机总结的更多相关文章

  1. Android ART运行时与Dalvik虚拟机

    这几天在做一个项目时需要在Android中使用OSGi框架(Apache Felix),于是在一个android 4.4.2 版本系统的某品牌的平板上实验. 实验内容很简单:把felix包里的feli ...

  2. java虚拟机和Dalvik虚拟机的区别

    java虚拟机和Dalvik虚拟机的区别: java虚拟机Dalvik虚拟机 java虚拟机基于栈. 基于栈的机器必须使用指令来载入和操作栈上数据,所需指令更多更多dalvik虚拟机是基于寄存器的 j ...

  3. 转 Android Dalvik虚拟机初识

    首先,让我们来思考下面几个问题: 什么是Dalvik虚拟机? Dalvik VM与JVM有什么区别? Dalvik VM有什么新的特点? Dalvik VM的架构是怎么样的? 首先,我得承认第一个问题 ...

  4. Android Dalvik虚拟机初识(转)

    原文地址:http://blog.csdn.net/andyxm/article/details/6126907 android虚拟机jvmjava优化linux内核 首先,让我们来思考下面几个问题: ...

  5. Android(java)学习笔记156:Java虚拟机和Dalvik虚拟机的区别

    Google于2007年底正式发布了Android SDK, 作为 Android系统的重要特性,Dalvik虚拟机也第一次进入了人们的视野.它对内存的高效使用,和在低速CPU上表现出的高性能,确实令 ...

  6. Dalvik虚拟机进程和线程的创建过程分析

    从前面Dalvik虚拟机的运行过程分析一文可以知道,Dalvik虚拟机除了可以执行Java代码之外,还可以执行Native代码,也就是C/C++函数. 这些C/C++函数在执行的过程中,又可以通过本地 ...

  7. Dalvik虚拟机的运行过程分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8914953 在前面一篇文章中,我们分析了Dal ...

  8. Dalvik虚拟机JNI方法的注册过程分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8923483 在前面一文中,我们分析了Dalvi ...

  9. Dalvik虚拟机简要介绍和学习计划

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8852432 我们知道,Android应用程序是 ...

  10. Dalvik虚拟机的启动过程分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8885792 在Android系统中,应用程序进 ...

随机推荐

  1. OpenCV2.4.9 + VS2012 + win10 配置

    Step1 下载opencv 2.4.9 pack Step2 解压到本地 我解压路径是: C:\OPENCV Step3 添加环境变量: 这里虽然把X64下的VC11(VC11对应VS2012的C+ ...

  2. 274 H-Index H指数

    给定一位研究者的论文被引用次数的数组(被引用次数是非负整数).写一个方法计算出研究者的H指数.H-index定义: “一位科学家有指数 h 是指他(她)的 N 篇论文中至多有 h 篇论文,分别被引用了 ...

  3. C# 调用带有输出参数的分页存储过程

    一.创建带有输出参数的分页存储过程 use StudentMISDB go select * from Course alter table Course go --update Course set ...

  4. nw.js开发第一个程序(html开发桌面程序exe)

    一.环境配置 windows系统 cnpm install node 下载nw.js https://github.com/nwjs/nw.js 找到download下载合适的版本 二.开发 项目目录 ...

  5. Tomcat环境的搭建

    一.Tomcat的简单介绍 大家应该知道平时所说的C/S和B/S系统架构:C/S架构是基于客户端C和服务端S的,B/S架构是基于浏览器B和S服务端的,B/S架构中的server就是web服务器. To ...

  6. VC++代码转换为QT代码问题总结

    一边开发一边总结......  QQ937113547

  7. CAD得到所有实体方法(网页版)

    主要用到函数说明: IMxDrawSelectionSet::AllSelect 得到当前空间的所有实体.详细说明如下: 参数 说明 [in,defaultvalue(NULL)] IMxDrawRe ...

  8. Luogu P1692 部落卫队

    解题思路 数据范围不是很大,那应该不是那些普遍的图论的算法.考虑搜索,用暴力解决.从1到N枚举每一个点的位置,搜索这个点事选还是不选.如果在这个点之前选到的点中又和他冲突的点,那就不选,要么就选. 附 ...

  9. instance_name,db_name,oracle_sid之间的关系

    一]对ORACLE_SID的理解 --------------------------------------------------------------------------------Ora ...

  10. webpack3 + vue 添加 serviceWorker

    新的vue脚手架已经可以自带pwa了,本文主要针对旧版的webpack. 先装三个插件: $npm i register-service-worker sw-precache-webpack-plug ...