概述

Android4.4以上开始使用ART虚拟机,在此之前我们一直使用的Dalvik虚拟机,那么为什么Google突然换了Android运行的虚拟机呢?答案只有一个:ART虚拟机更优秀。

1. Dalvik虚拟机基本知识介绍

Dalvik基本概念
Dalvik虚拟机是Android程序的虚拟机,其指令集基于寄存器架构,执行其特有的文件格式——dex字节码,主要负责完成对象生命周期管理、堆栈管理、线程管理、安全异常管理、垃圾回收等重要功能。

android使用的Java代码,跟Java 虚拟机类似,是Android中Java程序的运行基础。

但是dalvik虚拟机与Java虚拟机有较大区别:

1)、dalvik基于寄存器,而JVM基于stack
      2)、Dalvik执行的是特有的DEX文件格式,而JVM运行的是*.class文件格式。
优势:

1)、在编译时提前优化代码而不是等到运行时
      2)、 虚拟机很小,使用的空间也小;被设计来满足可高效运行多种虚拟机实例。

3)、常量池已被修改为只使用32位的索引,以 简化解释器

2、 Dalvik进程管理:
           dalvik进程管理是依赖于linux的进程体系结构的,如要为应用程序创建一个进程,它会使用linux的fork机制来复制一个进程(复制进程往往比创建进程效率更高)。
Zygote是一个虚拟机进程,同时也是一个虚拟机实例的孵化器,它通过init进程启动。首先会孵化出System_Server(android绝大多系统服务的守护进程,它会监听socket等待请求命令,当有一个应用程序启动时,就会向它发出请求,zygote就会FORK出一个新的应用程序进程).每当系统要求执行一个android应用程序时,Zygote就会运用linux的FORK进制产生一个子进程来执行该应用程序。
          不同的应用在不同的进程空间里运行,当一个虚拟机关闭或意外中止时不会对其它 虚拟机造成影响,可以最大程度的保护应用的安全和独立运行。

随着使用时间的增长,android系统会变得越来越慢。很多中高端的Android手机即使在硬件配置上比同时期的iPhone还要高不少,仍然会在长期使用之后变得反应迟钝。关于Android系统运行慢的原因众说纷纭,其中大家公认的一个因素,就是Android使用的Dalvik虚拟机的性能问题。

为此Google在2014年推出了新的虚拟机ART,在Android4.4系统中提供给用户试用,力图从根本上改善系统卡顿的问题 ,并且从Android5.0开始废弃了Dalvik,全面推行ART。

随着越来越多Android5.0及以上机型的面世,很多终端用户已经用上了配备ART虚拟机的Android系统。系统是否真的变快了,这还需要经过用户的考验,我们先看一下ART有哪些技术上的改进。

Dalvik和ART

众所周知,Android系统是以Linux为内核构建的。Google为了降低应用的开发难度,并将其适配到不同硬件配置的设备上,在Linux内核之上构建了一个虚拟机,Android应用使用java开发,运行在虚拟机之上。

Dalvik就是Android4.4及之前使用的虚拟机,它使用的是JIT(Just-In-Time)技术来进行代码转译,每次执行应用的时候,Dalvik将程序的代码编译为机器语言执行。随着硬件水平的不断发展以及人们对更高性能的需求,Dalvik虚拟机的不足日益突出。而应运而生的ART(Android RunTime)虚拟机,其处理机制根本上的区别是:它采用AOT(Ahead-Of-Time)技术,会在应用程序安装时就转换成机器语言,不再在执行时解释,从而优化了应用运行的速度。在内存管理方面,ART也有比较大的改进,对内存分配和回收都做了算法优化,降低了内存碎片化程度,回收时间也得以缩短。

下图是Google发布的使用不同性能测试工具时Dalvik和ART的得分对比:

ART运作原理

1) 内存管理

内存管理的优化是ART的一大改进。

ART虚拟机首先会从系统空间中取得足够的空间,这些空间在没有使用的时候并不占用物理内存,在使用的时候才分配物理内存,在不需要的时候及时归还给系统。ART 将分配到的空间根据需要托管给不同的算法进行管理,主要提供了如下几种分配算法来进行内存分配,它们的定义可以在ART源码定义中看到:

enum AllocatorType {

kAllocatorTypeBumpPointer,  // Use BumpPointer allocator, has entrypoints.

kAllocatorTypeTLAB,  // Use TLAB allocator, has entrypoints.

kAllocatorTypeRosAlloc,  // Use RosAlloc allocator, has entrypoints.

kAllocatorTypeDlMalloc,  // Use dlmalloc allocator, has entrypoints.

kAllocatorTypeNonMoving,  // Special allocator for non moving objects, doesn't have entrypoints.

kAllocatorTypeLOS,  // Large object space, also doesn't have entrypoints.

};

其中后二种是没有跳转表(entrypoints)的,我们主要了解一下前面4种的分配策略:

RosAlloc(Rows of slots Allocator)的分配策略:在Ros Alloc Space分配对象,是一种线性分配方式,将一个大的连续空间划分为多个片,每个片中只能分配固定大小的内存。这种分配方式有一个更加细粒度的结构,可以锁定独立的对象。

BumpPointer:在Bump Pointer Space中分配对象。每一次申请时,分配需要的size,返回end地址的值。然后将end后移sized,作为下一次申请的地址。这种分配采用不计数申请的方式,直到发生out of memory。采用Moving GC的方式进行回收。

TLAB(Thread Local Allocation Block):在由Bump Pointer Space提供的线程局部分配缓冲区中分配对象,按线程进行管理。每一个线程,从Bump Pointer Space中申请一个block,在线程内使用Bump Pointer的分配策略。由于每一个线程独立在自己的block中分配内存,避免了同步,可以提高效率。

DLMalloc:这是原Dalvik使用的算法 。在Dl Malloc Space分配对象,将memory划分成很多小的数据块,每一个块的前8个或者16个字节作为Header,使用链表来管理空闲的数据块。

使用这些不同算法来分配内存,与Dalvik相比可以有效的减少碎片化,由于碎片化减少,相应也就减少了GC的次数。除此之外,像TLAB这样的算法引入,也减少了申请内存时线程之间的竞争。

在内存回收方面,ART也提供了几种GC算法,GC算法与内存分配算法相对应,关系如下表:

ART在回收memory时,会依据进程状态选择不同的算法。除此之外,ART在GC时采用了读写锁的机制,减少了进程被挂起的时间,因此较之于Dalvik,GC时线程挂起的时间也相应缩短。

2) 代码执行

我们引用一张Google的图来看一下Android对apk的执行流程(图片从上往下阅读)

Java文件在编译成class文件,然后经过Android平台的dx工具转换为Dex文件后,同Native code(JNI)和资源一起打包成apk,apk安装到手机后解压出Dex文件。Dalvik会通过dexopt工具将Dex优化,成为Odex文件,Odex文件的效率比Dex高,但其中大部分代码仍然需要每次执行时编译;而ART则会将Dex通过dex2oat工具编译得到一个ELF文件,它是一个可执行的文件。

关于Java代码的执行过程,以一段简单的代码为例:

int a = 1;

int b = 2;

public int test() {

① int x = a;

② int y = b;

int z = a + b;

return z;

}

在执行这段Java代码时,Dalvik虚拟机先要把test()方法的每句代码转译成Dex代码,对其中的① ② 两句赋值语句,执行时需要在虚拟机中进行“指令读取—识别指令—跳转—实例操作”的解析过程;而ART中Java代码都被以方法为单位编译成汇编指令,执行上面这个方法的时候,① ② 两句代码只需要直接拷贝两个寄存器的值,各需要一条汇编指令就可以完成,省去了跳转、指令读取的过程,执行效率也就大大提高了。

总结

虚拟机从Dalvik换成ART后,Android系统的性能得到了一定程度的提升。不过ART与Dalvik相比也存在一些缺点,比较明显的表现就是,apk经过dex2oat预编译之后,占用的空间增加,因此Android ROM占用的空间更大。手机在安装下载的apk时,安装时间也明显变长。但在手机硬件配置越来越高的今天,与获得更佳的系统性能相比,这个缺点也就不那么引人注目了。

android 虚拟机介绍相关推荐

  1. DMMS工具介绍-更改Android虚拟机默认安装位置

    Android virtual devices  Manager工具 画红线部分为Android 虚拟机路径,其中不能包含中文路径,否则将导致虚拟机可能无法正常启动. 更改默认安装路径: 1.复制An ...

  2. 1.android体系结构介绍

    一.Android的介绍 android介绍见百度百科:Android的介绍,度娘把Android介绍的这么清楚,如果谷歌是Android的爹,那度娘就是娘了. 二.Android的架构图 andro ...

  3. Android开发介绍

    Android开发介绍 这个教程设计是帮助你学习基础的Android开发和快速搭建您的开发环境.这个是在我的Window 7上编写的,当然它也支持Linux(uBuntu).Mac OS其他支持And ...

  4. android虚拟机接收真实短信,向Android模拟器打电话发短信的简单方法

    在开发android应用程序时,有时候需要测试一下向android手机拨打电话发送短信时该应用程序的反应.譬如编写一个广播接收器,来提示用户有短信收到或者处理短信,就需要向该手机发送短信来进行测试.这 ...

  5. 重学Android基础系列篇(五):Android虚拟机指令

    前言 本系列文章主要是汇总了一下大佬们的技术文章,属于Android基础部分,作为一名合格的安卓开发工程师,咱们肯定要熟练掌握java和android,本期就来说说这些~ [非商业用途,如有侵权,请告 ...

  6. android 模拟器的使用(Android模拟器介绍及创建)

    做了这么久的android开发,一直想把在开发过程中积累的经验或问题总结一下,可是都没有时间,现在有一点点空闲,所以慢慢把我在android中遇到的问题整理一下写出来,供自己以后参考,也希望和大家一起 ...

  7. Android 的介绍

    想必每个初学者对Android都不甚了解,今天我们来了解一下初级的Android Android的发展史 Android的创始人:大家都知道苹果的创始人是乔布斯,而安卓的创始人则是安迪.鲁宾 1.20 ...

  8. Android虚拟机中安装软件方法

    Android虚拟机中安装软件方法 1.在android开发过程中,我们很多时候会用到模拟器来装载软件来测试,先装入内存卡,在安装是很麻烦的一件事,在这里介绍利用adb直接安装软件的办法: 1.1.启 ...

  9. Android 虚拟机进化史

    按时间顺序开始介绍吧 1. Dalvik or ART? 2. Android 诞生之初 --> 单纯的 Dalvik 2.1 Dalvik虚拟机概述 2.2 Dalvik虚拟机与Java虚拟机 ...

最新文章

  1. 深入浅出任务队列机制,非常浅
  2. DIV CSS display (block none inline)属性的用法教程
  3. 4.Vue 模板语法
  4. pandas切割字符串并保存为新列
  5. $GOPATH not set 问题解决方案
  6. 华为鸿蒙os2.0系统beta,华为发布HarmonyOS 2系统:万物互联时代鸿蒙大一统
  7. c语言 怎么把数据存储,急求如何将下列C语言程序数据存储到文件中?
  8. The Willpower Instinct(自控力,意志力)
  9. cool edit pro 2.1中文版未定义外部错误怎么解决
  10. 关于学习BEX5的问题
  11. axurerp9怎么生成html形式页面,Axure RP教程 Axure RP如何生成HTML文件
  12. 怎么把mp4转换成mp3?
  13. flush-hosts
  14. 主谓宾定状补......
  15. 极光会客厅:大型H5游戏如何登陆微信小游戏及游戏性能优化分享
  16. graphql入门使用-查询
  17. Unity3D: 精灵更换图片脚本实现
  18. Win10 DNS解析失败解决方法
  19. 【考研政治】2021肖八整理(毛中特部分)
  20. 《JavaEE开发技术》课程考试试题(A卷)

热门文章

  1. windows server 2012 使用包管理工具choco安装程序
  2. json.stringify()函数
  3. Hive视图与物化视图
  4. HTML背景图片和背景渐变
  5. LVGL - 在STM32上的移植
  6. bp神经网络和cnn神经网络,RNN神经网络适用于什么
  7. b区计算机专业调剂容易的学校,2021考研b区容易调剂的学校有哪些
  8. 微信小程序中数字取整
  9. kali下中英文输入任意切换
  10. 限制百度地图拖动范围限制,当超如范围时自动返回