Android ART虚拟机(一)

Android的应用程序开发语言首选的是java,所以Android虚拟机或多或少都会借鉴JVM中的一些设计思想和技术实现。虽然严格意义上讲Android的dalvik/art并不是纯正的java虚拟机(因为没有完全遵循JVM规范),但是本质上跟hotspot等jvm又有很多相似。所以先理解java虚拟机对理解Android虚拟机是会有很大帮助的。

java虚拟机解决的核心问题是:write once,run anywhere,为了这个目标,需要把java语言文件编译为中间状态的字节码bytecode,然后在运行阶段对具体的平台做转换(将字节码翻译成目标平台的机器码)。所以jit,interpreter,内存分配和回收,线程管理等都是为这个目标服务的。

JVM架构中的核心模块:

Java虚拟机的类加载机制,可以参考:JVM类加载

(1)Class loader和双亲委派模型

class loader提供了一种灵活的方式,帮助应用程序将字节码流以自定义的方式加载到虚拟机中。java虚拟机中通常存在几种class loader:

1)Bootstrap classloader

2)Extension classloader

3)System classloader

4)User classloader

Bootstrap classloader是c/c++语言编写的,它所加载的类通常位于JAVA_HOME/lib中,或者有-X bootclasspath指定,属于java的核心实现部分。

Extension classloader负责jre扩展目录中的各种类的加载,如JAVA_HOME/lib/ext目录下的内容。

System classloader 称为应用程序类加载器,用于加载CLASSPATH中的各种类对象,

可以通过classloader.getSystemClassLoader()获取,如果应用程序没有提供自定义的classloader,默认情况下系统将使用system classloader来加载应用程序中的类。

user classloader是应用程序提供,通常继承自java.lang.ClassLoader,并按照规范实现其中的接口。


(2)Runtime Data areas,

Java的内存分配,可以参考:Java内存分配

jvm运行过程中所需的数据区域,包括stack,heap,MethodArea等多个部分。

其中Program counter register区是实现java多线程管理的关键之一,每个java虚拟机线程都需要彼此独立的PC寄存器。如果被执行的是native方法,pc寄存器实际是没有定义的,因为native代码可以被物理硬件直接识别并执行,此时不需要模拟的pc寄存器。


(3)堆和垃圾回收

垃圾收集算法,可以参考:jvm垃圾回收

堆内存的特点是进程独立、线程共享。堆内存最流行的垃圾回收算法是“分代垃圾回收”。

1)Young Generation,年轻代内存,又分为eden,s0,s1,

2)old Generation,老年代内存。

3)Permanent Generation,永久代内存,用于存储和类、方法相关的Meta Data,不属于heap的范围。

绝大多数对象都是在YoungGeneration(年轻代)被分配,也在YoungGeneration被回收。当YoungGeneration空间被填满时,GC会进行Minor Collection(次回收),这次的回收不涉及Heap中的其他Generation。

       在Young Generation中,没有被回收的对象被转移到Tenured Generation,然后在Tenured Generation也会被填满,最终触发Major Generation(主回收),这次回收针对整个Heap。

       YoungGeneration中幸存的对象被转移到TenuredGeneration(老年代),但是ConcurrentCollector线程在这里进行MajorCollection,而在回收任务结束前空间被耗尽了,这时会触发Full Collections(Full GC)。

因为TenuredGeneration 的majorCollection过程较慢,如果TenuredGeneration空间小于YoungGeneration,会造成频繁的MajorCollection,肯定影响效率。通常serverJVM中,Young Generation 和 Tenured Generation空间比例为1:2,也即是说Young Generation的Eden和Survivor空间之和是整个Heap的1/3,这个比例可以通过-XX:NewRation=n参数来控制。

       PermGen,它是JVM用来存储无法在Java语言级描述的对象,这些对象分别是类和方法数据(与class loader有关),以及interned Strings(字符串驻留)。

       对于Perm Gen,如果出现OOM,log:java.lang.OutOfMemoryError:PerGen space

实在找不出问题所在,可以使用JVM的-verbose参数,这个参数会在后台打印日志,用来查看那个class loader加载了什么类。

       通过MAT工具,Open Query Browser à JavaBasics àClass loader Explorer 在Class loader Explorer面板,可以查看ClassLoader是否加载了过多的类。  

       什么样的对象会被GC回收?在GC发现通过任何reference chain(引用链)无法访问某个对象的时候,该对象即被回收。

       通常GC Roots是一个在current thread(当前线程)的call stack(调用栈)上的对象(如方法参数、局部变量),或者是线程自身,或者是systemclass loader(系统类加载器)加载的类,及nativecode(本地代码)保留的活动对象。

       StrongRef(强引用),通常创建的对象都是Strong Ref,于此对应的是强可达性,只有去掉强可达,对象才被回收。

       SoftRef(软引用),对应软可达性,只要有足够的内存,就一直保持对象,直到发现内存吃紧且没有Strong Ref时才回收对象。一般可用来实现缓存,通过java.lang.ref.SoftReference实现。

       WeakRef(弱引用),比SoftRef更弱,当发现不存在StrongRef时,立即回收对象而不必等到内存吃紧的时候,通过java.lang.ref.WeakReference和java.util.WeakHashMap类实现。


(4)Execution engine,执行引擎是虚拟机中的中枢系统,主流的jvm一般支持多种执行方式:

1)java字节码解释执行,可以参考:jvm 字节码执行引擎

2)在运行阶段根据一定的算法将使用频率高的字节码编译成native code(JIT),然后执行。JIT(just in time)相对于AOT的主要区别是JIT只有在程序运行过程中才会将部分热点代码编译成机器码(这在一定程度上加重了cpu的负担)。

3)在编译阶段将字节码直接转换成机器码,类似于ART虚拟机的AOT技术。


(5)基于寄存器和基于栈的java虚拟机的实现

java虚拟机执行字节码有多种实现方式,用的较多的是基于寄存器和基于栈。

基于栈的方式:

1)单条指令更紧凑,优于JVM执行的是字节码,不需要想基于寄存器的架构那样显性地指定源和目标,所以采用栈实现的方式可以减小单条指令的codesize;

2)可移植性强,基于寄存器的的虚拟机需要考虑很多与目标平台强相关的因素,如要根据硬件平台的真实寄存器的数量、他们的用途等,来实现虚拟机中的寄存器和真实世界中的寄存器之间的“映射关系”。相比来说,栈虚拟机没有这个考虑,所以通用性更好。

3)由于指令是基于栈来操作的,导致完成同一个任务所需的指令数比基于寄存器的架构要多。

4)从执行速度看,基于寄存器的架构更快。因为基于栈的方式需要更多的内存读写操作,而且需要更多的指令数。


ARTVM的框架:


Android虚拟机的核心系统包括:Runtime,ClassLoader system ,Execution Engine System,Heap Manager,GC system,JIT,JNI环境等等。

Runtime,代表了虚拟机的运行时态,起到管理员的作用;

JavaVM,是对虚拟机的抽象,每个进程最多只有一个实例存在;

JNIEnv,负责jni机制,并且是线程相关的。

ClassLoader system,类加载器,又细分:Boot Classloader,system classloader,Dex Classloader等,所有被加载的类及其组成元素由Classlinker统一管理,为了实现类似于elf中的动态延迟加载效果,Android vm使用了dexcache机制;

Execution engine,执行引擎,除了字节码解释执行的方式,还有aot技术。在art中,Interpreter,jit,aot三种执行方式是共存的。


art和dalvik两个vm虽然差别很大,但是对于应用程序来说,没有特别的要求,几乎完全透明,真正的区分的地方是应用程序的安装阶段:

Dalvik,如果当前系统配置的是dalvik,在应用程序安装阶段要对dex文件做odex优化,就是利用dexopt工具来生成odex文件。对于rom中的应用程序,即预装的,优化过程在编译阶段完成;对于第三方应用,在安装时由install系统负责优化,结果保存在/data/Dalvik-cache目录下,后缀是.odex。

art:如果配置的ART,应用安装阶段也有一次预处理,类似dalvik,只是art预处理使用的工具是dex2oat,输出的是linux标准执行文件elf file。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Android Java虚拟ART是一种全新的虚拟,它是Android Lollipop操作系统中默认的运行时环境,相比于旧版的Dalvik虚拟,它能够提供更好的性能和体验。 ART的最大特点是在使用前将字节码转换为器码,这样可以在运行时减少解释和编译的时间,从而提高应用程序的响应速度。此外,在ART中也引入了一些新的技术,例如预编译、AOT和热编译等,这些都能够优化应用程序的启动速度和运行效率。 在深入研究ART之前,必须先了解Java虚拟(JVM)的基本概念和原理。JVM是一种运行Java程序的虚拟,将Java源代码转换为字节码,再由虚拟解释执行。同样地,ART也采用相同的原理来实现应用程序的运行,只不过它将字节码转换为器码,从而提高了运行速度和效率。 因此,熟悉Java虚拟和ART的工作原理,能够帮助开发者更好地理解和优化应用程序的性能。此外,对于一些需要高效运行的应用场景(例如游戏、图像处理等),ART也能够提供更好的运行环境,提高应用程序的稳定性和响应能力。 总之,深入理解Android Java虚拟ART对于开发者来说非常重要,尤其是在需要优化应用程序性能和响应速度的情况下。只有深入了解ART的原理和特点,才能更好地应用它来提高应用程序的运行效率。 ### 回答2: Android Java虚拟ART是Android系统中最新的运行时环境。相较于旧有的Dalvik虚拟,ART采用预编译技术,将应用程序字节码一次性编译为本地器码,提高了应用程序的运行效率和响应速度,同时也降低了资源消耗。因此,深入理解Android Java虚拟ART对于Android开发者来说是非常必要的。 深入学习ART,我们需要了解其内部运作制,包括Dex编译、ClassLoader、Garbage Collection等关键概念。ART采用了AOT和JIT两种编译方式,也采用了一些新的优化方法,如Profile Guided Optimization(PGO)、Image Space Estimation等,以提高应用程序的可执行性和启动时间。 ART的ClassLoader实现了一种高效的动态加载技术,它使得应用程序可以在运行时动态更新代码库、插件包等,从而大大扩展了应用程序的功能和灵活性。同时ART的ClassLoader也是构建Android虚拟化环境的基础,它可以从不同的应用程序中加载开放的类,并为每个应用程序提供一个独立的执行环境。 最后,ART的Garbage Collection制实现了一种全新的分代收集算法,将耗费大量时间的垃圾回收操作分散到不同的虚拟堆内,从而大幅度提高了应用程序的性能和响应速度。 总之,深入理解Android Java虚拟ART对于Android开发者来说十分关键,它将为我们提供更为深入的开发思路和方法,使我们的应用程序更加高效,同时也为我们的Android应用程序开发添上浓墨重彩的一笔。 ### 回答3: Android Java虚拟ART (Android Runtime)是安卓4.4系统及以上版本中的默认虚拟。相比原先的Dalvik虚拟,ART可实现更高的性能和更好的系统稳定性。 ART的核心思想是AOT( Ahead of Time)编译。它在应用程序安装的时候就将应用程序代码转换成本地器指令并编译成器代码,以C/C++库的形式保存在设备上。相比Dalvik,在应用程序的执行过程中省去了JIT编译的时间和运算,能够提高应用程序的运行速度。 除此之外,ART还有几个重要的特点: 1. 超低功耗:ART的AOT编译技术使得应用执行时可以直接使用本地器指令,减少了CPU的时间浪费,使得应用程序的功耗更低。 2. 内存占用减少: ART允许应用程序在运行时进行类加载,实现更高效的内存管理。相比Dalvik虚拟,ART在处理内存和垃圾回收时能够更好地利用系统资源,减少了应用程序所占用的内存。 3. 支持快速应用开发:通过使用ART虚拟可以通过模块形式快速开发出具有更好体验的应用程序。 总之,深入理解Android Java虚拟ART需要着重理解ART AOT编译原理、内存管理制、以及对快速应用开发的支持。这些特点的综合优势使得安卓应用程序能够实现更快的运行速度、更低的功耗、更快的开发效率和更好的用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值