Android ART虚拟机

2024-06-05 14:18
文章标签 android 虚拟机 art

本文主要是介绍Android ART虚拟机,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转载自:https://blog.csdn.net/luoshengyang/article/details/45017207
Android与ios相比,一直被人诟病它的流畅性。android的流畅性问题,有一部分原因就归结于它的应用程序和部分系统服务是运行虚拟机之上的,也就是运行在Dalvik虚拟机之上,而ios的应用程序和系统服务都是直接执行本地机器指令的。除了使用ATR替换Dalvik之外,我们也应当看到,Android从3。0开始,就不遗余力地改进系统的流畅性。例如,3.0增加了对应用程序2D UI的硬件加速渲染,也就是GPU渲染。在此之前,应用程序的2D UI一直都是使用软件渲染,也就是CPU渲染。又如4.1通过Project Butter,在UI架构中引用了VSYNC、Triple Buffer和HWComposer等技术,极大地提高UI的流畅性。

ART之所以会比Dalvik快,是因为ART执行的是本地机器指令,而Dalvik执行的是Dex字节码,通过解释器执行。尽管Dalvik也会对频繁执行的代码进行JIT生成本地机器指令来执行,但毕竟在应用程序运行的过程中将Dex字节码翻译成本地机器指令也会影响到应用程序本身的执行,因此即使Dalvik使用了JIT,也在一定程度上也比不上直接就可以执行本地机器指令的运行时。

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

与Dalvik虚拟机垃圾回收机制一样,ART运行时垃圾收集机制也涉及到类似于Zygote堆、Active堆、Card Table、Heap Bitmap和Mark Stack等概念,如图一所示:
这里写图片描述

从图1可以看到,ART运行时堆划分为4个空间,分别是Image Space、Zygote Space、Allocation Space和Large Object Space。其中,Image Space 、Zygote Space、Allocation Space是在地址上连续的空间,称为Continuous Space,而Large ObjectSpace 是一些离散地址的集合,用来分配一些大对象,称为Discontinuous Space。

在Image Space和Zygote Space之间,隔着一段用来映射system@framework@boot.ar@classes.oat文件的内存。system@framework@boot.ar@classes.oat是一个OAT文件,它是由在系统启动类路径中的所有Dex文件翻译得到的,而Image Space空间就包含了那些需要预加载的系统类对象。这意味着需要预加载的类对象是在生成system@framework@boot.ar@classes.oat这个OAT文件的时候创建并且保存在文件system@framework@boot.ar@classes.oat中,以后只要系统启动类路径中的DEX文件不发生变化(即不发生更新升级),那么以后每次系统启动只需要将文件system@framework@boot.ar@classes.oat直接映射到内存即可,省去了创建各个类对象的时间。之前使用Dalvik虚拟机作为应用程序运行时,每次系统启动时,都需要为那些预加载的类创建类对象。因此,虽然ART运行时第一次启动时会比较慢,但是以后启动实际上会更快。
Zygote Space和Allocation Space与Dalvik虚拟机垃圾收集机制中的Zygote堆和Active堆的作用是一样的。Zygote Space在Zygote进程和应用程序进程之间共享的,而Allocation Space则是每个进程独占的。同样的,Zygote 进程一开始只有一个Image Space和一个Zygote Space。在Zygote进程fork第一个子进程之前,就会吧Zygote Space一分为二,原来的已经被使用的部分堆还叫Zygote Space,而未使用的那部分堆就叫Allocation Space。以后的对象都在Allocation Space上分配。Large Object Space就是一些离散地址的集合,用来分配一些大对象,比如分配图片。
通过上述这种方式,就可以使得Image Space和Zygote Space在Zygote进程和应用程序进程之间进行共享,而Allocation Space就每个进程都独立地拥有一份。注意,虽然Image Space和Zygote Space都是在Zygote进程和应用程序进程之间进行共享,但是前者的对象只创建一次,而后者的对象需要在系统每次启动时根据运行情况都重新创建一遍。

ART垃圾收集过程

这里写图片描述

ART运行的每一个Space都有不同的回收策略,ART运行时根据这个特性提供了Mark Sweep、Partial Mark Sweep和Sticky Mark Sweep等三种回收力度不同的垃圾收集器。其中,Mark Sweep的垃圾回收力度最大,它会同时回收Zygote Space、Allocation Space和Large Object Space的垃圾,Partial MarkSweep的垃圾回收力度居中,它只会同时回收Allocation Space 和Large Object Space的垃圾,而Sticky Mark Sweep的垃圾回收力度最小,它只会回收Allocation Stack的垃圾,即上次GC以后分配出来的又不再使用了的对象。力度越大的垃圾收集器,回收垃圾时需要的时候也就越长。这样我们就可以在应用程序运行的过程中根据不同的情景使用不同的垃圾收集器,那就可以更有效地执行垃圾回收过程。另外在Android 5.0以后的ART中,还引入了Semi-Space(SS)GC和Generaltional Semi-Space(GSS)、Mark-Compact(Mc)GC的三个Compaction GC,可以有效地解决内存碎片问题。

Semi-Space(SS)GC和Generational Semi-Space(GSS)GC是ART运行时引进的两个Compacting GC。它们的共同点都具有一个From Space和一个To Space。在GC执行期间,在From Space分配的还存活的对象会被一次拷贝到To Space中,这样就可以达到消除内存碎片的目的。
与SS GC相比,GSS GC 还多了一个Promote Space。当一个对象是在上一次GC之前分配的,并且在当前GC中仍然是存活的,那么它就会被拷贝到Promote Space中,而不是To Space中。这相当于是简单地将对象划分为新生代和老生代的,即在上一次GC之前分配的对象属于老生代的,而在上一次GC之后分配的对象属于新生代的。一般来说,老生代对象的存活性要比新生代的久,因此将它们拷贝到Promote Space中去,可以避免每次执行SS GC或者GSS GC时,都需要对它们进行无用的处理。
总结来说,SS GC和GSS GC的执行过程就如下图所示:
这里写图片描述
这里写图片描述

如上图所示,Bump Pointer Space 1和Bump Pointer Space2就是我们前面说的From Space和To Space。

除了Semi-Space GC和Generational Semi-Space GC,ART运行时还引入了第三种Compacting GC:Mark-Compact(MC) GC。这三种GC虽然都是Compacting GC,不过它们的实现方式却有很大不同。SSGC和GSS GC需两个Space来压缩内存,而MC GC只需一个Space来压缩内存。
Mark-compact GC主要是针对ART运行时正在使用的Bump Pointer Space进行压缩,如下图所示:
这里写图片描述

从图1可以看出,当Mark-Compact GC执行完成之后,原来位于Bump Pointer Space上的仍然存活的对象会被一次移动至原Bump Pointer Space的左侧,并且按地址从小到大紧凑地排列在一起。这个过程不需要借助于额外的Space来完成。这一点是Mark-Compact GC与Semi-Space GC、Generational Semi-Space GC的显著区别。

ART 与Dalvik比较

1、ART有很多GC方式可以选择,而Dalvik只有一种GC方式。
2、ART通过额外记录新分配的对象来支持更好的轻量级Sticky GC。
ART中新增的轻量级回收kGcTypeSticky只回收上次GC后再Allocation Space中新分配的垃圾对象,Heap 类的成员函数RecordAllocation首先是记录当前已经分配的内存字节数以及对象数,为了Sticky GC,还要接着再将新分配的对象压入到Heap类的成员变量allocation_stack_描述的Allocation Stack中去,而Dalvik虚拟机直接将新分配出来的对象记录在Live Bitmap中。如果不能成功将新分配的对象压入到Allocation Stack中,就说明上次GC以来,新分配的对象太多了,因此这时候就需要执行一个Sticky GC,将Allocation Stack里面的垃圾进行回收,然后再尝试将新分配的对象压入到Allocation Stack中,直到成功为止。
3、大内存块额外单独管理,可以提高内存分配和回收效率。
4、减少Suspend时间。
对于并行GC,在Handle Dirty Object阶段是在挂起ART运行时线程的前提下进行的,因此,如果把所有的Dirty Card 都放在Handle Dirty Object阶段处理,那么就会可能会造成应用程序停顿时间过长。于是,ART运行时就在并行Marking阶段也帮忙着处理Dirty Card,通过这种方式尽量减少在Handle Dirty Object阶段需要处理的Dirty Card,以达到减少应用程序因为GC造成的停顿时间。另外ART在垃圾回收过程中,也减少了挂起非GC线程的次数。

这篇关于Android ART虚拟机的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1033293

相关文章

Android数据库Room的实际使用过程总结

《Android数据库Room的实际使用过程总结》这篇文章主要给大家介绍了关于Android数据库Room的实际使用过程,详细介绍了如何创建实体类、数据访问对象(DAO)和数据库抽象类,需要的朋友可以... 目录前言一、Room的基本使用1.项目配置2.创建实体类(Entity)3.创建数据访问对象(DAO

Android WebView的加载超时处理方案

《AndroidWebView的加载超时处理方案》在Android开发中,WebView是一个常用的组件,用于在应用中嵌入网页,然而,当网络状况不佳或页面加载过慢时,用户可能会遇到加载超时的问题,本... 目录引言一、WebView加载超时的原因二、加载超时处理方案1. 使用Handler和Timer进行超

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标了,所以就需要看下mtk的camera2的相关横屏保存图片功能, 如何实现实现横屏保存图片功能 如图所示: 2.mtk

android应用中res目录说明

Android应用的res目录是一个特殊的项目,该项目里存放了Android应用所用的全部资源,包括图片、字符串、颜色、尺寸、样式等,类似于web开发中的public目录,js、css、image、style。。。。 Android按照约定,将不同的资源放在不同的文件夹中,这样可以方便的让AAPT(即Android Asset Packaging Tool , 在SDK的build-tools目

Android fill_parent、match_parent、wrap_content三者的作用及区别

这三个属性都是用来适应视图的水平或者垂直大小,以视图的内容或尺寸为基础的布局,比精确的指定视图的范围更加方便。 1、fill_parent 设置一个视图的布局为fill_parent将强制性的使视图扩展至它父元素的大小 2、match_parent 和fill_parent一样,从字面上的意思match_parent更贴切一些,于是从2.2开始,两个属性都可以使用,但2.3版本以后的建议使

Android Environment 获取的路径问题

1. 以获取 /System 路径为例 /*** Return root of the "system" partition holding the core Android OS.* Always present and mounted read-only.*/public static @NonNull File getRootDirectory() {return DIR_ANDR