您的位置:首页 > 其它

浅析dalvik虚拟机JIT技术的实现

2014-03-31 14:44 134 查看
一、 说明

据说Android 2.2的虚拟机dalvik使用了JIT技术,使其运行速度快了5倍。dalvik解释并执行程序,JIT技术主要是对多次运行的代码进行编译,当再次调用时使用编译之后的机器码,而不是每次都解释,以节约时间。5倍是测试程序测出的值,并不是说程序运行速度也能达到5倍,这是因为测试程序有很多的重复调用和循环,而一般程序主要是顺序执行的,而且它是一边运行,一边编译,一开始的时候提速不多,所以真正运行程序速度提高不是特别明显。

二、 JAVA虚拟机主要的优化技术

1. JIT(Just
In Time)

最开始指在执行前编译,但是到现在已经发展成为,一开始解释执行,只有被多次调用的程序段才被编译,编译后存放在内存中,下次直接执行编译后的机器码

1) method方式:以函数或方法为单位进行编译

2) trace方式:以trace为单位进行编译(可以把循环中的内容作为单位编译),此方法也包含method

2. AOT(Ahead
Of Time)

在程序下载到本地时就编译成机器码,并存储在本地存在硬盘上,以加快运行程度,用此种方式,可执行的程序会变大四五倍

三、 dalvik中JIT的实现

每启动一个应用程序,都会相应地启动一个dalvik虚拟机,启动时会建立JIT线程,一直在后台运行。当某段代码被调用时,虚拟机会判断它是否需要编译成机器码,如果需要,就做一个标记,JIT线程不断判断此标记,如果发现被设定就把它编译成机器码,并将其机器码地址及相关信息放入entry
table中,下次执行到此就跳到机器码段执行,而不再解释执行,从而提高速度。

四、 dalvik
JIT部分代码分析

android 2.2代码还未发布,而2.1代码中已经加入JIT部分,只是默认未打开,以2.1代码为例对其原理进行分析,源码位置:$ANDROID_SRC/dalvik/vm/

1. 核心文件

1) vm/interp/Jit.c

供外界调用的入口

2) vm/compiler/compiler.c

核心函数的实现

3) vm/compiler/Frontend.c

编译method和trace的实现

2. 全局变量

1) gDvmJit

所有与JIT相关的数据及结构都存储于此,各个程序通过它访问JIT资源

3. 开关

1) dvmCompilerStartup() (vm/compiler/Compiler.c) 在虚拟机启动时调用

2) dvmCompilerShutdown() (vm/compiler/Compiler.c) 在虚拟机关闭时调用

4. 线程

1) compilerThreadStart() (vm/compiler/Compiler.c)

被dvmCompilerStartup() 调用,在虚拟机运行过程中一直生存的线程,while循环判断是否有代码需要编译,如果有,则调用dvmCompilerDoWork()对其进行编译

5. 编译成字节码

doCompilerdoWork()又分method和trace两种情况进行编译

1) dvmCompilerMethod() (vm/compiler/Frongend.c)

2) dvmCompilerTrace() (vm/compiler/Frongend.c)

其中的:dvmCompilerMIR2LIR(),dvmCompilerAssembleLIR()(MIR和LIR都是解释层的中间表示)逐层翻译成机器码

6. 编译后字节码的存储

1) dvmcompilerSetupCodeCache()
(vm/compiler/Compiler.c)

gDvmJit.codeCache:使用mmap分配(1024x1024),用于存在编译后的代码

gDvmJit.codeCacheByteUsed:codeCache的使用情况

gDvmJit.codeCacheFull:codeCache是否已写满

gDvmJit.pJitEntryTable:entry表,每个trace对应一个entry

7. 其它线程对JIT资源的访问

以下是一个示例,说明从主函数到JIT的调用关系如下:

AndroidRuntime::Start()->startVm()->_JNIEnv::CallStaticVoidMethod()->Check_CallStaticVoidMethodV()->CallStaticVoidMethodV()->dvmCallMethodV()->dvmInterpret()->dvmMterpStd()->dalvik_mterp()->Dalvik_java_lang_reflect_Method_invokeNative()->dvmInvokeMethod()->dvmInterpret()->dvmJitCheckTraceRequest()->dvmjitLookupAndAdd()

主要函数解释如下:

1) dvmJitLookupAndAdd()

判断是否有相对某段程序的字节码可用,如果有则返回其地址,如果没有,则做标记,以通知编译线程对其进行编译

2) dvmCheckJit()

此函数被define成CHECK_JIT(),它来判断什么条件时认为需要编译
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: