精华内容
下载资源
问答
  • Android Dalvik

    2011-03-07 09:45:46
    Android Dalvik 虚拟机,想了解Android Dalvik 的朋友看过来
  • 进入 Android Dalvik 虚拟机,android dalvik介绍 Dalvik 虚拟机的特点——掌握 Android 程序的运行原理 Android 系统的架构采用分层思想,这样的好处是拥有减少各层之间的依赖性、便于独 立分发、容易收敛问题和...
  • Android Dalvik虚拟机

    2019-03-26 18:03:57
    Android Dalvik虚拟机Dalvik虚拟机的特点--掌握Android 程序的运行原理Dalvik 虚拟机概述Dalvik 虚拟机与Java 虚拟机的区别Java 虚拟机运行的是Java 字节码, Dalvik 虚拟机运行的是Dalvik 字节码。Dalvik可执行文件...

    Dalvik虚拟机的特点–掌握Android 程序的运行原理

    Dalvik 虚拟机概述

    Dalvik 虚拟机作为Android 平台的核心组件, 拥有如下儿个特点:
    • 体积小, 占用内存空间小:
    • 专有的DEX可执行文件格式, 体积更小, 执行速度更快;
    • 常侄池采用32 位索引值, 寻址类方法名、字段名、常呈更快;
    • 基千寄存器架构, 并拥有一套完整的指令系统;
    • 提供了对象生命周期管理、堆栈管理、线程管理、安全和异常管理以及垃圾回收等重要功能;
    • 所有的Android 程序都运行在Android 系统进程里, 每个进程对应着一个Dalvik 虚拟机实例。

    Dalvik 虚拟机与Java 虚拟机的区别

    Java 虚拟机运行的是Java 字节码, Dalvik 虚拟机运行的是Dalvik 字节码。

    传统的Java 程序经过编译, 生成Java 字节码保存在class 文件中, Java 虚拟机通过解码class 文件中的内容来运行程序。而Dalvik 虚拟机运行的是Dalvik 字节码, 所有的Dalvik 字节码由Java字节码转换而来,并被打包到一个DEX (Dalvik Executable)可执行文件中。Dalvik虚拟机通过解释DEX文件来执行这些字节码。
    

    Dalvik可执行文件体积更小。

    AndroidSDK中有一个叫dx的工具负责将Java字节码转换为Dalvik字节码。dx工具对Java类文件重新排列,消除在类文件中出现的所有冗余信息,避免虚拟机在初始化时出现反复的文件加载与解析过程。一一般情况下,Java类文件中包含多个不同的方法签名,如果其他的类文件引用该类文件中的方法, 方法签名也会被复制到其类文件中,也就是说,多个不同的类会同时包含相同的方法签名,同样地,大量的字符串常量在多个类文件中也被重复使用。这些冗余信息会直接增加文件的体积,同时也会严重影响虚拟机解析文件的效率。dx工具针对这个间题专门做了处理,它将所有的Java 类文件中的常量池进行分解, 消除其中的冗余信息,重新组合形成一个常量池,所有的类文件共享同一个常量池。dx工具的转换过程如图3-1所示。由千dx工具对常量池的压缩,使得相同的字符串、常量在DEX文件中只出现一次, 从而减小了文件的体积。
    在这里插入图片描述

    Java虚拟机与Dalvik虚拟机架构不同。

    Java虚拟机基于栈架构。程序在运行时虚拟机需要频繁的从栈上读取或写入数据,这个过程需要更多的指令分派与内存访问次数, 会耗费不少CPU时间, 对千像手机设备资源有限的设备来说, 这是相当大的一笔开销。
    Dalvik 虚拟机基于寄存器架构。数据的访问通过寄存器间直接传递, 这样的访问方式比基千栈方式要快很多。

    Dalvik 虚拟机是如何执行程序的

    Android 系统的架构采用分层思想, 这样的好处是拥有减少各层之间的依赖性、便千独立分发、容易收敛问题和错误等优点。Android 系统由Linux 内核、函数库、Android 运行时、应用程序框架以及应用程序组成。
    在这里插入图片描述
    Zygote 提供了三种创建进程的方法:
    • forkO, 创建一个Zygote 进程(这种方式实际不会被调用);
    • forkAndSpecialize(), 创建一个非Zygote 进程:
    • forkSystemServer(), 创建一个系统服务进程。

    其中, Zygote 进程可以再fork() 出其他进程, 非Zygote 进程则不能fork 其他进程, 而系统服务进程在终止后它的子进程也必须终止。

    当进程fork 成功后, 执行的工作就交给了Dalvik 虚拟机。Dalvik 虚拟机首先通过loadClassFromDexO函数完成类的装载工作, 每个类被成功解析后都会拥有一个ClassObject类型的数据结构存储在运行时环境中,虚拟机使用gDvm.JoadedClasses 全局哈希表米存储与查询所有装载进来的类,随后,字节码验证器使用dvmVerifyCodeFlowO函数对装入的代码进行校验,接着虚拟机调用FindClassO函数查找并装载main方法类,随后调用dvmlnterpretO函数初始化解释器并执行字节码流。整个过程如图3-6所示。
    在这里插入图片描述

    关干Dalvik 虚拟机JIT (即时编译)

    JIT (Just-in-time Compilation, 即时编译),又称为动态编译,是一种通过在运行时将字节码翻译为机器码的技术, 使得程序的执行速度更快。
    主流的几T包含两种字节码编译方式:
    • method方式:以函数或方法为单位进行编译。
    • trace方式:以trace为单位进行编译。

    method 方式很好理解, 那什么是trace 方式呢?在函数中一般很少是顺序执行代码的,多数的代码都分成了好儿条执行路径,其中函数的有些路径在实际运行过程中是很少被执行的, 这部分路径被称为“冷路径“, 而执行比较频繁的路径被称为“热路径"。采用传统的method 方式会编译整个方法的代码, 这会使得在“冷路径” 上浪费很多编译时间, 并且耗费更多的内存: trace 方式编译则能够快速地获取“ 热路径” 代码, 使用更短的时间与更少的内存来编译代码。
    目前,Dalvik 虚拟机默认采用trace 方式编译代码,同时也支持采用method 方式来编译。

    展开全文
  • Android虚拟机Dalvik(略谈Android Dalvik虚拟机)
  • 详细讲解了Android_Dalvik_虚拟机初始和架构方向,想了解Android dalvik虚拟机的值得一看。
  • 下一节,介绍Dalvik指令集Android Dalvik虚拟机之Dalvik指令集-Smali汇编解析 Dalvik虚拟机为自己专门设计了一套指令集,并且制定了自己的指令格式与调用规范。我们将Dalvik指令集组成的代码称为Dalvik汇编代码,将...

    下一节,介绍Dalvik指令集Android Dalvik虚拟机之Dalvik指令集-Smali汇编解析

    Dalvik虚拟机为自己专门设计了一套指令集,并且制定了自己的指令格式与调用规范。我们将Dalvik指令集组成的代码称为Dalvik汇编代码,将这种代码表示的语言称为Dalvik汇编语言(Dalvik汇编语言并不是正式的语言,只是描述Dalvik指令集代码的一种称呼)。

    1. Dalvik指令格式

    一段Dalvik汇编代码由一系列Dalvik指令组成,指令语法由指令的位描述与指令格式标识来决定。位描述约定如下:

    • 每16位的字采用空格分隔开来。

    • 每个字母表示4位,每个字母按顺序从高字节开始,排列到低字节。每4位之间可能使有竖线“|”来表示不同的内容。

    • 顺序采用A~Z的单个大写字母作为一个4位的操作码,op表示一个8位的操作码。

    • “Ø”来表示这字段所有位为0值。

    以指令格式“A|G|op  BBBB  F|E|D|C”为例:

    指令中间有两个空格,每个分开的部分大小为16位,所以这条指令由三个16位的字组成。第一个16位是“A|G|op”,高8位由A与G组成,低字节由操作码op组成。第二个16位由BBBB组成,它表示一个16位的偏移值。第三个16位分别由F,E,D,C共四个4位组成,在这里它们表示寄存器参数。

    单独使用位标识还无法确定一条指令,必须通过指令格式标识来指定指令的格式编码。它的约定如下:

    • 指令格式标识大多由三个字符组成,前两个是数字,最后一个是字母。

    • 第一个数字是表示指令有多少个16位的字组成。

    • 第二个数字是表示指令最多使用寄存器的个数。特殊标记“r”标识使用一定范围内的寄存器。

    • 第三个字母为类型码,表示指令用到的额外数据的类型。取值见下表。

    还有一种特殊的情况是末尾可能会多出另一个字母,如果是字母 s 表示指令采用静态链接,如果是字母 i 表示指令应该被内联处理。指令格式标识的类型码如下:

    助记符                                 位大小                                        说明
    b 8 8位有符号立即数
    c 16,32 常量池索引
    f 16 接口常量(仅对静态链接格式有效)
    h 16 有符号立即数(32位或64位数的高值位,低值位为0)
    i 32 立即数,有符号整数或32位浮点数
    m 16 方法常量(仅对静态链接格式有效)
    n 4 4位的立即数
    s 16 短整型立即数
    t 8,16,32 跳转,分支
    x 0 无额外数据

    以指令格式标识 22x 为例:

    第一个数字2表示指令有两个16位字组成,第二个数字2表示指令使用到2个寄存器,第三个字母x表示没有使用到额外的数据。

    另外,Dalvik指令对语法做了一些说明,它约定如下:

    • 每条指令从操作码开始,后面紧跟参数,参数个数不定,每个参数之间采用逗号分开。

    • 每条指令的参数从指令第一部分开始,op位于低8位,高8位可以是一个8位的参数,也可以是两个4位的参数,还可以为空,如果指令超过16位,则后面部分依次作为参数。

    • 如果参数采用“vX”的方式表示,表明它是一个寄存器,如v0,v1等。这里采用v而不用r是为了避免与基于该 虚拟机架构本身的寄存器命名产生冲突,如ARM架构寄存器命名采用r开头。

    • 如果参数采用“#+X”的方法表示,表明它是一个常量数字。

    • 如果参数采用“+X”的方式表示,表明它是一个相对指令的地址偏移。

    • 如果参数采有“kind@X”的方式表示,表明它是一个常量池索引值。其中kind表示常量池类型,它可以是“string”(字符串常量池索引),“type”(类型常量池索引),“field”(字段常量池索引)或者“meth”(方法常量池索引)。

    以指令 “op vAA, string@BBBB” 为例:指令用到了1个寄存器参数 vAA,并且还附加了一个字符串常量池索引 string@BBBB,其实这条指令格式代表着 const-string 指令。

    2. DEX文件反汇编工具

    目前DEX可执行文件主流的反汇编工具有:BakSmali与Dedexer。两者的反汇编效果都不错,在语法上也有着很多的相似处。下面通过代码对比两者的语法差异,测试代码采用上一节的Hello.java,首先使用dx工具生成Hello.dex文件,然后在命令提示符下输入以下命令使用baksmali.jar反汇编 Hello.dex:

    $ java -jar baksmali.jar -o baksmaliout Hello.dex

    命令成功执行会在baksmaliout目录下生成Hello.smali文件,使用文本编辑器打开它:

    # virtual methods
    .method public foo(II)I
        .registers 5
        .parameter
        .parameter
        .prologue
        .line 3
        add-int v0, p1, p2
        sub-int v1, p1, p2
        mul-int/2addr v0, v1
        return v0
    .end method

    执行以下命令使用ddx.jar(Dedexer的jar文件)反汇编Hello.dex:

    $ java -jar ddx.jar -d ddxout Hello.dex

    命令成功执行后,会在ddxout目录下生成Hello.ddx文件,使用文本编辑器打开它,foo()函数代码如下:

    .method public foo(II)I
    .limit registers 5
    ; this: v2 (LHello;)
    ; parameter[0] : v3 (I)
    ; parameter[1] : v4 (I)
    .line 3
        add-int v0, v3, v4
        sub-int v1, v3, v4
        mul-int/2addr  v0,v1
        return v0
    .end method

    两种反汇编代码大体的结构组织是一样的,在方法名,字段类型与代码指令序列上它们保持一致,具体的差异表现在一些语法细节上。对比之下,可以发现如下不同点:

    • 前者使用.registers指令指定函数用到的寄存器数目,后者在.registers指令前加了limit前缀。

    • 前者使寄存器p0作为this引用,后者使用寄存器v2作为this引用。

    • 前者使用一条.parameter指令指定函数一个参数,后者则使用parameter数组指定参数寄存器。

    • 前者使用.prologue指令指定函数代码起始处,后者却没有。

    • 两者寄存器表示法不同,前者使用p命名法,后者使用v命名法。

    BakSmali提供反汇编功能的同时,还支持使用Smali工具打包反汇编代码重新生成dex文件,这个功能被广泛应用于apk文件的修改,补丁,破解等场合,因而更加受到开发人员的青睐。本系列blog默认都将采用Smali语法格式。

    3. 了解Dalvik寄存器

    Dalvik虚拟机基于寄存器架构,在代码中大量地使用到了寄存器。Dalvik虚拟机是作用于特定架构的CPU上运行的,在设计之初采用了ARM架构,ARM架构的CPU本身集成了多个寄存器,Dalvik将部分寄存器映射到了ARM寄存器上,还有一部分则通过调用栈进行模拟。注意:Dalvik中用到的寄存器都是32位的,支持任何类型,64位类型用2个相邻寄存器表示。(这节具体的内容还是看书吧!非虫的书)

    4. 两种不同的寄存器表示方法——v命名法与p命名法

    前面曾多次提到v命名法与p命名法,它们是Dalvik字节码中两种不同的寄存器表示方法。下面我们来看看,它们在表现上有一些什么样的区别。

    假设一个函数使用到M个寄存器,并且该函数有N个参数,根据Dalvik虚拟机参数传递方式中的规定:参数使用最后的N个寄存器,局部变量使用从v0开始的前(M-N)个寄存器。如前面的小节中,foo()函数使用到了5个寄存器,2个显式的整形参数,其中foo()函数是Hello类的非静态方法,函数被调用时会传入一个隐式的Hello对象引用,因此,实际传入的参数数量是3个。根据传参规则,局部变量将使用前2个寄存器,参数会使用后3个寄存器。

    v命名法采用以小写字母“v”开头的方式表示函数中用到的局部变量与参数,所有的寄存器命名从v0开始,依次递增。对于foo()函数,v命名法会用到v0,v1,v2,v3,v4等五个寄存器,v0与v1用来表示函数的局部变量寄存器,v2表示被传入的Hello对象的引用,v3与v4分别表示两个传入的整形参数。

    p命令法对函数的局部变量寄存器命名没有影响,它的命名规则是:函数中引入的参数命名从p0开始,依次递增。对于foo()函数,p命名法会用到v0,v1,p0,p1,p2等五个寄存器,v0与v1同样用来表示函数的局部变量寄存器,p0表示被传入的Hello对象的引用,p1与p2分别表示两个传入的整形参数。

    对于有M个寄存器及N个参数的函数foo()来说,v命名法与p命名法的表现形式如下表所示。通过观察可以发现,使用p命名法表示的Dalvik汇编代码,通过寄存器的前缀更容易判断寄存器到底是局部变量寄存器还是参数寄存器,在Dalvik汇编代码较长,使用寄存器较多的情况下,这种优势将更加明显。表:v命名法与p命名法:

    v命名法                                            p命名法                                    寄存器含义
    v0 v0 第一个局部变量寄存器
    v1 v1 第二个局部变量寄存器
    ... ... 中间的局部变量寄存器依次递增
    vM-N p0 第一个参数寄存器
    ... ... 中间的参数寄存器分别依次递增
    vM-1 pN-1 第N个参数寄存器

    5. Dalvik字节码的类型,方法与字段表示方法

    Dalvik字节码有着一套自己的类型,方法与字段表示方法,这些方法与Dalvik虚拟机指令集一起组成了一条条的Dalvik汇编代码。

    5.1. 类型

    Dalvik字节码只有两种类型,基本类型与引用类型。Dalvik使用这两种类型来表示Java语言的全部类型,除了对象与数组属于引用对象外,其他的Java类型都是基本类型。BakSmali严格遵守了DEX文件格式中的类型描述符定义。类型描述符对照如下表:

    语法                                      含义
    V void,只用于返回值类型
    Z boolean
    B byte
    S short
    C char
    I int
    J long
    F float
    D double
    L Java类类型
    [ 数组类型

    每个Dalvik寄存器都是32位大小,对于小于或等于32位长度的类型来说,一个寄存器就可以存放该类型的值。而像J,D等64位的类型,它们的值是使用相邻两个寄存器来存储的,如 v0 与 v1,v3 与 v4等。

    L类型可以表示Java类型中的任何类。这些类在Java代码中以 package.name.ObjectName方式引用,到了Dalvik汇编代码中,它们以Lpackage/name/ObjectName; 形式表示,注意最后有个分号,L表示后面跟着一个Java类,package/name/表示对象所在的包,ObjectName表示对象的名称,最后的分号表示对象名结束。例如:Ljava/lang/String;相当于java.lang.String。

    [类型可以表示所有基本类型的数组。[后面紧跟基本类型描述符,如 [I 表示一个整型一维数组,相当于Java中的int[]。多个[在一起时可用来表示多维数组,如 [[I 表示int[][],[[[I表示 int[][][]。注意多维数组的维数最大为255个。L与[ 可以同时使用用来表示对象数组。如 [Ljava/lang/String;就表示Java中的字符串数组。

    5.2. 方法 

    方法的表现形式比类名要复杂一些,Dalvik使用方法名,类型参数与返回值来详细描述一个方法。这样做一方面有助于Dalvik虚拟机在运行时从方法表中快速地找到正确的方法,另一方面,Dalvik虚拟机也可以使用它们来做一些静态分析,比如Dalvik字节码的验证与优化。方法格式如下:

    Lpackage/name/ObjectName;->Methodname(III)Z

    在这个例子中,Lpackage/name/ObjectName;应该理解为 个类型,MethodName为具体的方法名,(III)Z是方法的签名部分,其中括号 内的III为方法的参数(在此为三个整型参数),Z表示方法的返回类型(boolean类型)。

    下面是一个更为复杂的例子:

    method(I[[IILjava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;

    按照上面的知识,将其转换成Java形式的代码应该为:

    String method(int, int[][], int, String, Object[])

    BakSmali生成的方法代码 .method指令开始,以 .end method指令结束,根据方法类型的不同,在方法指令开始前可能会用“”号加以注释。如“# virtual methods”表示这是一个虚方法,“#direct methods”表示这是一个直接方法。

    5.3. 字段

    字段与方法很相似,只是字段没有方法签名域中的参数与返回值,取而代之的是字段的类型。同样,Dalvik虚拟机定位字段与字节码静态分析时会用到它。字段的格式如下:

    Lpackage/name/ObjectName;->FieldName:Ljava/lang/String;

    字段由类型(Lpackage/name/ObjectName;),字段名(FieldName)与字段类型(Ljava/lang/String;)组成。其中字段名与字段类型中间用冒号“”隔开。

    BakSmali生成的字段代码以 .field指令开头,根据字段类型的不同,在字段指令的开始可能会用“#”号加以注释,如:“# instance fields”表示这是一个实例字段,“#static fields”表示这是一个静态字段。

    原文:https://my.oschina.net/fhd/blog/365337

    展开全文
  • Android Dalvik文件 编译方法
  • Android Dalvik虚拟机结构及机制剖析》《Android Dalvik虚拟机结构及机制剖析》《Android Dalvik虚拟机结构及机制剖析》《Android Dalvik虚拟机结构及机制剖析》《Android Dalvik虚拟机结构及机制剖析》《Android ...
  • Android Dalvik虚拟机结构及机制剖析:第1卷 Dalvik虚拟机结构剖析》是一本以情景方式对Android的源代码进行深入分析的书,内容广泛,主要从Dalvik虚拟机整体结构、获取和编译Dalvik虚拟机的源码、源码分析辅助...
  • Android Dalvik虚拟机(尽管现在被art取代,但不代表它一无是处,了解dalvik有助于理解art)在Android 4.4之前,Dalvik一直是Android中默认的虚拟机,后面推出了ART运行环境机制,逐步完全取代了DalvikDalvik 和...

    Android Dalvik虚拟机(尽管现在被art取代,但不代表它一无是处,了解dalvik有助于理解art)

    在Android 4.4之前,Dalvik一直是Android中默认的虚拟机,后面推出了ART运行环境机制,逐步完全取代了Dalvik。Dalvik 和art都可以支持已经转换为.dex格式的java应用程序的运行。

     

    一、Dalvik VM,JVM的差异:

    1)多数JVM都是基于堆栈的,而DalvikVM是基于寄存器的,通常基于栈的机器需要更多的指令,而基于寄存器的机器指令更大。基于stack的vm必须使用指令来载入stack上的数据,或使用指令来操纵数据,所以需要更多的指令。

     

     

    尽管Dalvik虚拟机 运行的是java语言,但是它不是按照java虚拟机规范来实现的,所以两者并不兼容。

     

    2)在java se程序中,java类会被编译成一个或多个字节码文件.class,然后打包到jar文件,而后jvm虚拟机会从相应的Class文件和jar文件中获取相应的字节码;

    Android应用的java类在编译成Class文件后,会通过一个工具dx将所有的class文件转换成一个DEX文件,而后dalvik从中读取指令和数据。

     

    3)Dalvik VM经过优化,允许在有限的内存中同时运行多个虚拟机实例,并且每一个Dalvik VM应用作为一个独立的Linux进程执行。

     

    二、Dalvik VM的特征

    DEX文件格式会把所有的Class文件内容整合到一个文件中,减少了整体的文件尺寸和IO操作,也提高了类的查找速度。原来每个类文件中的常量池,在dex文件中由一个常量池负责管理。

     

    每个虚拟机实例都是一个独立的进程空间,zygote是一个虚拟机实例的孵化器,当系统需要执行一个android应用程序,zygote就会fork一个子进程来执行该应用程序。

    这样做的优点:zygote进程是系统启动时创建的,他会完成虚拟机的初始化、库的加载、预制类库的加载和初始化等操作;当系统需要一个新的虚拟机实例,zygote通过复制自身,快速的提供了一个子系统;对于一些只读性的系统库来说,所有虚拟机实例都和zygote共享一块内存区域,节省了内存开销。

     

    基于寄存器的dalvikVM虽然在硬件通用性上差一些,但是在代码的执行效率上更快,可以更有效的减少冗余指令的分发和减少内存的读写访问。

     

    三、Dalvik VM的架构

     

    在AOSP源码中,Dalvik vm源码在dalvik/目录下,被编译成libdvm.so;dalvik/libdex会被编译成libdex.a静态库,作为dex工具使用,dalvik/dexdump是.dex文件的反编译工具;

     

    Dalvik虚拟机的架构如图:


    Dalvik VM各个子目录的功能:

    Dalvikvm:虚拟机命令行调用入口文件的目录,用来解释命令行参数,调用库函数接口等。

    Dexdump:生成dex文件反编译查看工具。

    Dexlist:生成查看dex文件里所有类的方法的工具。

    Dexopt:生成dex优化工具。

    Dvz:生成从zygote请求生成虚拟机实例的工具。

    Dx:生成从java字节码转换为dalvik机器码的工具。

    Hit:生成显示堆栈信息/对象信息的工具。

    Libcore:dalvik vm核心类库,提供给上层的应用程序调用。

    Libnativehelper:dalvik vm核心库的支持库函数。

     

    四、Dalvik vm命令

    Dalvik vm支持命令行参数,可以通过系统参数影响虚拟机的行为。

    1)  基本命令

    通过setprop 设置系统特性

    Adb shell setprop name value

    这些系统设定是在zygote进程中处理的。

    2)  扩展的jni检测

    扩展jni检测会导致系统变慢,但可以发现一个bug,这个功能通过-Xcheck:jni命令行激活。

    参数ro.kernel.Android.checkjni,dalvik.vm.checkjni覆盖了前一个参数,这两个参数会影响到这个功能

    3)  断言

    Dalvik vm支持java语言的断言表达式,默认是关闭的,可以通过dalvik –ea 参数设置。

    4)  字节码校验和优化

    Dalvik vm尝试预校验dex文件中的所有类,降低class的负担,使用优化提升运行性能,上述功能是通过dexopt命令实现的。

    两个标记控制jit优化和校验:-Xverify和-Xdexopt。

    5)  Dalvik VM的运行模式

    包括三种独立的解释内核:快速(fast),可移植(portable),调试(debug),快速解释器是为当前平台优化的,可能包括手动优化的汇编文件;可移植解释器是用C写的,可在广泛的平台的上使用;调试解释器是可移植解释器的变种,包括了支持程序分析(Profiling)和单步。

    6)  死锁预测

    如果虚拟机以WITH_DEADLOCK_PREDECTION参数编译,死锁预测器会在-Xdeadlockpredict参数中使能。这个特性让虚拟机移植跟踪对象的锁获取顺序,如果程序试图以与之前看到不同的顺序获取一些锁,vm会log一个warning。

    7)  Dump堆栈跟踪

    Dalvik vm 收到SIGQUIT(kill -3或ctrl -\)时,会为所有线程dump所有的堆栈跟踪,默认写入log,也可以写入一个文件。

    Dalvik.vm.stack-trace-file特性指定要将线程堆栈追踪写入的文件名。

    8)  Dex文件和校验

    VM提供了-Xcheckdexsum参数,如果设置了,在内容使用前所有的dex文件都会进行和校验。

    出于性能考虑,优化过的dex文件和校验被取消了。

     

    五,ART机制基础

    在ART环境下,应用在第一次安装的时候,字节码会预先编译成机器码,使其成为真正的本地应用,这个过程称为预编译(AOT,ahead-of-time),从而加快应用的启动和执行。

    ART完全兼容dalvik的字节码格式dex文件。

    相对于dalvik垃圾回收的两次暂停(遍历阶段,标记阶段),art只暂停一次。在遍历阶段,应用不需要暂停,标记阶段的暂停时间也缩短了,这是基于packard pre-cleaning技术。

    Art源码在AOSP工程下的art/目录。

    其中的compiler:主要负责Dalvik字节码到本地代码的转换,编译为libart-compiler.so;

    Dex2oat:完成dex文件到ELF文件转换,编译为dex2oat;AOT技术是在编译阶段将java代码翻译成针对目标平台的机器码,但是对于第三方的apk事先不知道它将运行于那个具体的硬件平台,aot就不适合了,所以在apk在配置了art的设备上安装时,会调用一个精简的编译器dex2oat来完成动态的翻译工作。

    Runtime:ART运行时源代码,编译为libart.so。


    展开全文
  • 资源名称:Android Dalvik虚拟机结构及机制剖析资源截图: 资源太大,传百度网盘了,链接在附件中,有需要的同学自取。
  • Google原创的Android Dalvik虚拟机讲义
  • android Dalvik JVM ART

    2017-06-03 08:24:47
    android Dalvik JVM ART JVM、DVM(Dalvik VM)和ART虚拟机对比 http://blog.csdn.net/evan_man/article/details/52414390 1、 JVM基于栈:JVM字节码中,局部变量会被放入局部变量表中,继而被压入堆栈供操作码...

    android Dalvik JVM ART

    JVM、DVM(Dalvik VM)和ART虚拟机对比
    http://blog.csdn.net/evan_man/article/details/52414390

    1、
    JVM基于栈:JVM字节码中,局部变量会被放入局部变量表中,继而被压入堆栈供操作码进行运算,当然JVM也可以只使用堆栈而不显式地将局部变量存入变量表中。
    Dalvik基于寄存器:寄存器存取速度比栈快,dvm基于寄存器,可以根据硬件实现最大的优化,比较适合移动设备
    基于寄存器的虚拟机对于更大的程序来说,在它们编译的时候,花费的时间更短、速度更快。Dalvik字节码中,局部变量会被赋给65536个可用的寄存器中的任何一个,
    Dalvik指令直接操作这些寄存器,而不是访问堆栈中的元素。
    2、
    Java虚拟机运行java bytecode,Dalvik虚拟机运行的是其专有的文件格式Dex(dex文件格式可以减少整体文件尺寸—dex工具会去除.class文件冗余信息,减少了I/O操作,提高了类的查找速度,odex:为了在运行过程中进一步提高性能,对dex文件的进一步优化)
    JVM字节码:由.class文件组成,每个文件一个class。JVM在运行的时候为每一个类装载字节码。
    Dalvik字节码:Dalvik程序只包含一个.dex文件,该文件包含了程序中所有的类。Java编译器创建了JVM字节码之后,对.class文件进行合并、优化,重新把它们编译成Dalvik字节码,
    然后把它们写进一个.dex文件中(目的是把不同class文件重复的东西只需保留一份写入.dex文件,多个.class文件变成一个dex文件需考虑方法数过限问题(方法数超65535时报错,可引出MultiDex技术)), 同时Dalvik的dx编译器删除.class文件,。
    该过程包括翻译、重构、解释程序的基本元素(常量池–常量池32位索引、类定义、数据段)。
    常量池:描述了所有的常量,包括引用、方法名、数值常量等。
    类定义:包括了访问标志、类名等基本信息。
    数据段:包含各种被VM执行的函数代码以及类和函数的相关信息(如DVM所需要的寄存器数量、局部变量表、操作数堆栈大小),还有实例变量。
    JVM:    .java -> .class -> .jar
    Dalvik VM: .java -> .class -> .dex (dexopt优化) -> .odex
    3、
    Dalvik虚拟机在android2.2之后使用JIT (Just-In-Time即时编译)技术,但与传统JVM的JIT并不完全相同 
    4、
    Dalvik主要是完成对象生命周期管理,堆栈管理,线程管理,安全和异常管理,以及垃圾回收等等重要功能。   
    5、
    Dalvik负责进程隔离和线程管理:
    每一个Android应用在底层都会对应一个独立的Dalvik虚拟机实例(linux进程),其代码在虚拟机的解释下得以执行。   
    每一个Android应用的线程都对应一个Linux线程,虚拟机因而可以更多的依赖操作系统的线程调度和管理机制
    (Dalvik 允许在有限的内存中同时运行多个虚拟机的实例,每一个Dalvik应用作为一个独立的Linux 进程执行。独立的进程可以防止在虚拟机崩溃的时候所有程序都被关闭)   

    dalvik进程管理是依赖于linux的进程体系结构的,如要为应用程序创建一个进程,它会使用linux的fork机制来复制一个进程(复制进程往往比创建进程效率更高)。
    Zygote是一个虚拟机进程,也是一个虚拟机实例的孵化器,它通过init进程启动,它会完成虚拟机的初始化、库的加载、预制类库和初始化的操作。Zygote首先会孵化出System_Server(android绝大多系统服务的守护进程,它会监听socket等待请求命令,
    当有一个应用程序启动时,就会向它发出请求,zygote就会FORK出一个新的应用程序进程(虚拟机实例)).每当系统要求执行一个android应用程序时,Zygote就会运用linux的FORK进制产生一个子进程来执行该应用程序

    Dalvik虚拟机实现位于dalvik/目录下,dalvik/vm是虚拟机的实现部分,被编译为libdvm.so,
    而dalvik/libdex被编译成libdex.a静态库作为dex工具库;
    dalvik/dexdump是.dex文件的反编译工具。
    虚拟机的可执行程序位于dalvik/dalvikvm中,将被编译为dalvikvm可执行程序

    ART(Android Runtime)
    ART能够把应用程序的字节码转换为机器码,是Android5.0以后所使用的一种新的虚拟机。

    ART 与 Dalvik
    不同点:
    Dalvik采用的是JIT(just in time)技术,字节码都需要通过即时编译器转换为机器码
    ART采用Ahead-of-time(AOT:Android系统自带的dex2oat工具把APK里面的.dex文件转化成OAT文件,OAT文件是一种Android私有ELF文件格式,它不仅包含有从DEX文件翻译而来的本地机器指令,还包含有原来的DEX文件内容)技术,
    应用在第一次安装的时候,字节码就会预先编译成本地机器码,之后每次打开应用,执行的都是本地机器码,去除了运行时的解释执行,效率更高,启动更快(运行时内存占用空间较少同样意味着编译二进制需要更高的存储)。
    ART同时也改善了性能、垃圾回收(Garbage Collection)、应用程序除错以及性能分析。

    相同点:
    ART模式的系统里,同样存在DexClassLoader类,包名路径也没变,只不过它的具体实现与原来的有所不同,但是接口是一致的。
    ART运行时就是和Dalvik虚拟机一样,实现了一套完全兼容Java虚拟机的接口

    展开全文
  • android dalvik虚拟机结构及机制剖析 第二版,详细介绍Android虚拟机值得阅览
  • 本系列丛书共分2卷,《Android Dalvik虚拟机结构及机制剖析——第2卷 Dalvik虚拟机各模块机制分析》为第2卷,在第1卷的基础上,采有情景分析的方式对Android Dalvik虚拟机的源代码进行了有针对性的分析,围绕类加载...
  • 安卓Dalvik虚拟机相关知识点总结Java虚拟机与Dalvik虚拟机的区别 Java虚拟机运行的是Java字节码(保存在class文件中),Dalvik运行的是Dalvik字节码(由Java字节码转化而来,打包到DEX文件中)。 Dalvik可执行文件更...
  • Android dalvik 虚拟机与ART虚拟机区别
  • Android Dalvik虚拟机结构及机制剖析 Dalvik虚拟机各模块机制分析 第2卷》
  • Android Dalvik ART

    2017-02-17 22:01:18
    概念 Dalvik 是运行Android程序的虚拟机,是Google等厂商合作开发的Android移动设备平台的核心组成部分之一。Dalvik允许在优先的内存中同时运行多个虚拟机实例,每个应用作为一个独立的linux进程。Dalvik支持运行....
  • 移动开发的安全分析工具,与soot有关.Dexpler: converting android dalvik bytecode to jimple for static analysis with soot
  • Android Dalvik虚拟机结构及机制剖析 第2卷
  • Android Dalvik虚拟机结构及机制剖析 第1卷
  • Modify Android dalvik vm heapsize
  • Android Dalvik源码

    2013-09-18 09:53:56
    Android 虚拟机系统Java层源码
  • android Dalvik虚拟机

    千次阅读 2018-08-01 20:54:53
    android5.0中,ART运行时取代了Dalvik虚拟机。虽然Dalvik虚拟机不再使用,但是它曾经的作用是不可磨灭的。因此,在研究ART运行时的垃圾收集机制之前,先理解Dalvik虚拟机的垃圾收集机制也是很重要和有帮助的。因此...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 59,807
精华内容 23,922
关键字:

安卓dalvik