了解一下,Android 10中的ART虚拟机(I)

缘起

从今天开始,对Android 10中的ART进行“了解一下”之旅。我本来以为一篇就能拿下,但谁想谷歌从8.0开始对ART进行了更细致和难度更高的改进。粗看了几遍代码,我觉得谷歌不管怎么样还是非常值得国内大厂的学习。改进了这么多,却很少在公开场合宣传。以至于我们误以为人家没干啥。一看代码,好多不认识的地方,好多重构,改进之处。原来,人家一直在努力,在完善....。

关于AOSP的持续改进,这里先举个例子,以后会讲。Android 10中(应该是2018年9月提交的代码)有一个工具叫view_compiler,就是将我们的布局文件转成java代码。这样,我们在渲染布局的时候就不需要读xml然后再解析它,而是直接运行这段代码就完成了布局(包含其中各种控件的添加之类的)。下面是View Compiler的说明。

以上是view_compiler的说明,README中说这是一个实验性的东西...感兴趣的同学可以试一下。权当新年福利。

回到本文,ART目前可能是AOSP中除了kernel外功能最复杂的模块了。所以分了几部分来专门了解一下Android 10中的ART。这一次我们先看看ART中有哪些工具,分别是干什么用的,涉及哪些知识。我大概列了几个比较关注的工具/子模块,如下所示。你要是都知道的话就厉害了

  • dalvikvm:art/dalvikvm

  • dexdiag、dexlayout:代码都在art/dexlayout

  • dexdump:dalvik/dexdump

  • dex2oat:art/dex2oat。我们的老朋友了。这篇讲不了。需要补充基础知识的话请好好阅读《深入理解Android:Java虚拟机ART》一书。

  • dexlist:art/dexlist

  • dexoptanlayzer:art/dexoptanalyzer

  • oatdump:art/oatdum

  • profman:art/profman

  • dexfuzz:art/tools/dexfuzz

  • dexmaker:external/dexmaker

  • vogar:external/vogar

  • caliper:external/vogar

下面我们对来了解一下这些模块。

了解一下dalvikvm

dalvikvm是java虚拟机程序,注意,它就好像是java程序一样。Android上我们其实最熟悉的java虚拟机程序是app_process,也就是zygote。我看了下app_process和dalvikvm的代码。dalvikvm更纯粹,它不会启动Android那套复杂的东西。所以,我看AOSP源码中dalvikvm主要是用来启动一些java测试jar,和android fwk里的那些包没太大关系,更贴近纯java。

了解一下,dexdiag

dexdiag是手机上可运行的一个程序,我试了下,貌似是dump出某个java进程内存映射的情况。

比如adb shell dexdiag --verbose 3285,结果如下:

dexdiag把3285这个java进程映射的各种文件(各种.oat、.vdex文件)的映射信息展示了出来。但我现在还不确定这个玩意具体有啥用,被谁用到。以后碰到再补上。

了解一下,dexlayout

dexlayout是AOSP对ART虚拟机进一步优化的好东西。下面是它的官方说明:

dexlayout是8.0后引入的,它能根据profile的信息对dex文件里的不同信息进行重排。比如,可能把经常调用的函数挪到一起去。这样可充分利用计算机工作的重要基础原理——局部性原理。为什么会有这个优化呢?我猜测谷歌应该不是拍脑子想出来的,而可能有比较稳准狠的检测手段。这就很体现技术力量了。比如,虽然我们可以设计7nm的芯片,但能设计芯片的软件却大部分是外国产品....。很多公司把绝大部分精力花在用户能看得到的地方,却忽视了工具,检测技术的积淀....

dexlayout在主机上也可以运行。方法如下:

dexlayout -t am中间目录/dex/classes.dex。

运行结果是这样的:

这是我在主机上使用dexlayout工具查看am编译的dex文件的结果。具体咋用的我还没研究,后续可能会补充。

注意,这个图中展示了dex文件的一些内容。我发现其中多了一些我在写ART一书时没有碰到的东西,比如MethodHandleCallSiteId。这两个是什么玩意?

了解一下,dex 039版本

不看不知道,一看吓一跳。我在ART一书里研究的时候,dex文件格式还是037版本。到AOSP 9的时候已经升级到039了。主要改了什么呢?谷歌官方文档还是比较详细的有说明:

以上信息可参考官网,地址为https://source.android.com/devices/tech/dalvik/dex-format。

MethodHandler和CallSiteId其实是java里一个比较高级的功能,涉及到如何让java虚拟机支持动态语言。这个就很厉害了。其结果是,JVM以后会不会跑个诸如javascript这样的语言?

JVM支持这个功能的话,我粗浅的推测这可能会对国产某编译器极具创新的改动有比较大的影响。现在有点担心国产编译器选择这条前无古人后无来者的路是否正确了。Anyway,勇者必胜,试错也是大功劳

关于JVM如何支持动态语言,我找了两个比较典型的资料,各位感兴趣的可以看一下。

  1. https://www.pnfsoftware.com/blog/android-o-and-dex-version-38-new-dalvik-opcodes-to-support-dynamic-invocation/

  2. https://mydailyjava.blogspot.com/2015/03/dismantling-invokedynamic.html

相关内容我也截图给大家解解馋。

上面两个图解释了jvm支持动态语言调用的实现(Method Handles)。感兴趣的童鞋尽快补齐相关基础知识哈。我觉得很有用。里边提到说用这种方式貌似比反射的效率会高点(但是这个方式本意上不是替代反射的....)

了解一下,dexlist

dexlist好像是把dex文件里的方法给列出来。下面是运行的结果示意:

抱歉,这个dexlist啥usage信息都打不出来,简单粗暴得很

了解一下,dexoptanalyzer

dexoptanalyzer是用来判断某个dex文件是否需要优化。以下使用说明。

我在想,这玩意有这么神奇?对一个输入dex文件能判断是否需要哪种优化?我感觉可能是结合了当是否有机器码之类的来综合做判断。我试了几个纯dex文件,返回的都是1(kDex2OatFromScratch,就是需要从头到尾生成机器码

了解一下,profman

profman大家应该不陌生,就是生成性能profile的。然后机器码生成的时候能根据profile做有针对性的生成,而不是一股脑都生成。基于profile的机器码生成有个专业术语,叫Profile Guided Optimization(PGO)。PGO是一个目前比较流行的编译优化手段。Android在这块其实也是跟随了微软、苹果的脚步。

谷歌在提升APP运行速度这块貌似没有搞什么所谓的颠覆性创新,而是把其它公司或领域中常用的,好用的,被实践证明过有效的方法拿来。比如Play Store上就搞了PGO。下面是infoq上关于基于云端的PGO的介绍。想法其实很简单。

https://www.infoq.com/news/2019/04/play-cloud-art-profiling-android/

其实就是把多个人本地生成的profile文件(匿名方式,不涉及个人隐私相关的信息)传到云端,然后其他人从play store上下载app的时候连带一个profile文件也被下载过来。然后,这个新下载的app安装时将根据下载过来的profile生成机器码。在没有云端PGO的时候,需要每个人自己运行这个app一段时间后,积累了一些profile信息后才生成更有针对性的机器码。显然,云端PGO,这个技术手段听起来非常自然。

PGO现在很流行,包括iOS的xcode也支持PGO了。我没记错的话号称能提升10%以上的效率。微软的Visual Studio也支持。并且还有一篇比较好的基础知识文章介绍,地址如下:

https://docs.microsoft.com/en-us/cpp/build/profile-guided-optimizations?view=vs-2019

profman相关的内容以后我想介绍下,我也很好奇里边到底都是啥数据。

了解一下,dexfuzz

dexfuzz是一个很有意思的东西。它其实是一个测试工具。其思想是这样的。jvm很复杂,对吧?所以要做大量的测试。而测试代码如果都是人写的话,难免有考虑不全的地方。dexfuzz的作用就是随机对dex文件做一些修改,这样可以生成生成更多,更少见的测试case

dexfuzz比较好的介绍资料见

https://community.arm.com/developer/tools-software/oss-platforms/b/android-blog/posts/the-art-of-fuzz-testing

上面文章的内容的部分截图如下:

dex文件也不能随便乱改,这样会导致字节码校验(这个校验不是文件md5校验,而是非法操作校验,比如new一个基础类型的对象这种java里根本不存在的操作之类的)通不过去。所以可以改一下跳转的目标之类的地方。通过这种方式测验的jvm更经得起考验

了解一下,dexmaker,vogar,caliper

dexmaker是用来生成dex字节码的。它是linkedin提供的一套API,可以动态直接生成dex字节码文件,这样的话,相当于可以动态添加功能了。我查到的资料看dexmaker主要配合测试使用。

我在国内网站上搜索了下dexmaker的用法,好像有很大一部分是用于做插件化处理。而国外几乎都是配合Mockito。dexmaker的官方说明如下

vogar,caliper也是用来测试的。它和dexmaker有一定关系,因为我看dexmaker的说明文档里提到vogar了。

  • vogar可以做性能测试,可参考https://stackoverflow.com/questions/8220549/simple-benchmark-testing-with-vogar。 这个网页里有比较详细的介绍vogar的用法。

  • caliper:caliper是一个基于vogar的性能测试工具。详情可参考https://github.com/google/caliper/wiki/CaliperOnAndroid

后续的安排

AOSP 10源码撸了大概五天,发现其中有一些需要了解的知识,比如APEX、ART等。接下来会对这些东西做一系列的“了解”。在此也欢迎大家提供一些目标,好让我们的"了解Android 10”系列飞得更远一点。

最后的最后

  • 我期望的结果不是朋友们从我的书、文章、博客后学会了什么知识,干成了什么,而应该是说,神农,我可是踩在你的肩膀上的喔。

  • 关于学习方面的问题,我已经讨论完了。后面这个公众号将对一些基础的技术,新技术做一些学习和分享。也欢迎你的投稿。不过,正如我在公众号“联系方式”里说的那样——郑渊洁在童话大王《智齿》里有一句话令我印象深刻,大意是“我有权保持沉默,但你说的每一句话都可能成为我灵感的源泉”。所以,影响不是单向的,很可能我从你那学到的东西更多。

神农和朋友们的杂文集

长按识别二维码关注我们

  • 10
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
### 回答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虚拟机ARTAndroid系统最新的运行时环境。相较于旧有的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编译原理、内存管理机制、以及对快速应用开发的支持。这些特点的综合优势使得安卓应用程序能够实现更快的运行速度、更低的功耗、更快的开发效率和更好的用户体验。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值