【Android Dalvik虚拟机探索之路系列】之一:Dalvik虚拟机简介
来源:互联网 发布:linux vim安装包 编辑:程序博客网 时间:2024/06/06 05:38
作者:郭嘉
邮箱:allenwells@163.com
博客:http://blog.csdn.net/allenwells
github:https://github.com/AllenWells
【Android SDK程序逆向分析与破解系列】章节索引
【Android SDK程序逆向分析与破解系列】之一:Android安装程序APK分析
【Android SDK程序逆向分析与破解系列】之二:Android可执行程序DEX分析(一)
【Android SDK程序逆向分析与破解系列】之三:Android可执行程序DEX分析(二)
【Android SDK程序逆向分析与破解系列】之四:Android可执行程序ODEX分析
【Android SDK程序逆向分析与破解系列】之五:Android APK的静态分析
一 Dalvik虚拟机的特点
Android Dalvik虚拟机出自于Dan Bomstein之手,它作为Android平台的核心组件,具有以下几个方面的特点。
- 体积小,占用内存空间小;
- 专有的DEX可执行文件,体积更小,执行速度更快;
- 常量池采用32位索引值,寻址类方法名、字段名和常量更快;
- 基于寄存器架构,并拥有一套完整的指令系统;
- 提供了对象的生命周期管理、堆栈管理、安全管理和异常管理以及垃圾回收等重要功能
- 所有的Android程序都运行在Android的系统进程里,每个进程对应着一个Dalvik虚拟机实例。
二 Dalvik虚拟机和Java虚拟机的区别
1 Dalvik虚拟机运行的是Dalvik字节码,Java虚拟机运行的是Java字节码。
2 Dalvik虚拟机基于寄存器,指令执行较快,但是需要更多的指令缓冲,指令更易失效。Java虚拟机基于栈,指令指令缓冲空间小,但执行相对较慢,需要耗费更多的CPU时间。
3 Dalvik虚拟机使用dex格式打包类文件,各个类中重复的字符串可以只保存一次,更加节省空间。Java虚拟机使用class格式打包类文件。
Android SDK使用DX工具将Java字节码转换为Dalvik字节码,生成DEX文件,常见的优化如下所示:
- 将get/put指令中的field index转换为byte offset – 加快实例成员变量访问速度。
- 将boolean/byte/char/short变种的get/put指令统一转换为32位的get/put指令 – 减小VM解释器的大小,从而更有效地利用CPU的i-cache。
- 将高频调用的函数,例如String.length,转换为inline函数 – 消除函数调用开销。
- 移除空函数,例如Object. -消除空函数调用。
- 将可以预先计算的数据进行预处理,例如预先生成VM根据class name查询class的hash table – 节省Dex文件加载时间以及内存占用空间。
jar文件转换为DEX文件的过程如下图所示:
三 Dalvik虚拟机启动和执行程序的流程
- Android系统启动并加载内核;
- 执行init进程,init进程进行设备初始化工作,然后读取inic.rc文件并启动系统中重要的外部程序Zygote;
- Zygote启动后,首先初始化Dalvik虚拟机,然后启动system_server并进入Zygote模式,通过socke等候命令。
- 当执行Android程序时,system_server进程通过Binder IPC方式发送命令给Zygote,Zygote收到命令后通过fork自身创建一个Dalvik虚拟机实例来执行应用程序入口函数。当fork成功后,执行工作就由Dalvik虚拟机来完成。
Zygote启动流程如下图所示:
Dalvik执行程序流程
- 虚拟机线程
- 装载程序类,由loadClassFromDex()函数完成,解析成功的类会拥有一个ClassObject类型的数据存储在运行时环境中,Dalvik虚拟机使用gDvm.loadedClasses()全局哈希表来存储与查询装载进来的类;
- 验证字节码,由dvmVerifyCodeFlow()函数对装入的代码进程校验;
- 查找主类,由FindClass()函数查找并装载main()方法类;
- 执行字节码流,由dvmInterpre()函数来初始化解析器并执行字节码流。
Zygote提供了三种创建进程的方法:
- fork(),创建一个Zygote进程,该方式不常用。
- forkAndSpecialize(),创建一个非Zygote进程。
- forkSystemService(),创建一个系统服务进程。
四 Dalvik虚拟机的即时编译
即时编译(Just in time Compilation),又称动态编译,是一种运行时将字节码翻译成机器码的技术。
JIT包含两种编译方式:
- method方式:这个很好理解,就是以函数或方法为单位进行编译。
- trace方式:程序在真正执行的时候很少会顺序执行,因此会分为,冷路径:不经常被执行的路径。热路径:经常被执行的路径。所谓trace方式编译,就是可以快速获取热路径代码,使用更短的时间和更少的内存来编译代码。
Dalvik虚拟机默认使用trace方式编译代码,同时也保留了method方式。
- -
- 【Android Dalvik虚拟机探索之路系列】之一:Dalvik虚拟机简介
- 【Android Dalvik虚拟机探索之路系列】之二:Dalvik汇编语言
- Android Dalvik虚拟机简介
- Android Dalvik虚拟机简介
- android之Dalvik虚拟机
- ANDROID的DALVIK虚拟机简介
- android的Dalvik虚拟机简介
- android的Dalvik虚拟机简介
- Dalvik虚拟机简介
- Dalvik虚拟机简介
- Dalvik虚拟机简介
- Dalvik虚拟机简介
- 【编程语言】Android--Dalvik虚拟机简介
- Android定制JVM—Dalvik虚拟机简介
- Android Dalvik虚拟机初识
- Android虚拟机Dalvik
- Android Dalvik虚拟机初识
- Android Dalvik虚拟机介绍
- openstack网络(neutron)模式之GRE的基本原理
- Xcode中不用一行代码实现button圆角
- Linux中Mysql安装与使用(CentOS-6.5:mysql-5.5.27)
- 浅析三层架构与MVC模式的区别
- LeetCode 5 Longest Palindromic Substring
- 【Android Dalvik虚拟机探索之路系列】之一:Dalvik虚拟机简介
- TCP/IP详解学习笔记(2)-数据链路层
- [前端] nodejs中流(stream)的理解
- C#三层架构登陆实例
- markdown编辑器使用说明
- OpenCV中Mat属性step,size,step1,elemSize,elemSize1
- Android学习笔记(二)HelloWorld
- JBoss启动时报错
- VS2010之应用积累(待完善)