9102年了,还不知道Android为什么卡?

2021-01-29    分类: 网站建设

导读

最近华为方舟编译器要开源了,笔者去看了下发布会PPT,发现作为一名Android开发者,PPT中所介绍的知识点我居然不能完全看懂?于是乎恶补了下PPT中的内容,整理成本文。

在开发阶段Java源代码在开发阶段打包成.dex文件,C语言直接就是.so库,因为C语言本身就是编译语言。

在用户手机中,APK中的.dex文件(字节码)会被解释为.oat文件(机器码)运行在ART虚拟机中,.so库则为计算机可以直接运行的二进制代码(机器码),两份机器码要互相调用肯定是有开销的。

下面就来阐述下为什么两份机器码会不同。

这边需要深入理解字节码->机器码的编译过程,在图上虽然都被编译成了机器码,都能被硬件直接调用,但是两份机器码的性能,效率,实现方式相差甚多,这主要是由以下两个点造成的:

  • 编程语言不同导致编译出的字节码不同导致编译出的机器码不同。
  • 举个例子,针对同样是静态语言的C和Java,对int a + b 的运算
  • C语言可以直接加载内存,在寄存器中计算,这是由于C语言是静态语言,a和b是确定的int对象。

在Java中虽然定义对象我们也要明确的指出对象的类型,例如int a = 0,但是Java拥有动态性,Java拥有反射,代理,谁也不敢保证a在被调用时还是int类型,所以Java的编译需要考虑上下文关系,即具体情况具体编译。

所以连字节码已经不同了,编译出的机器码肯定不同。

运行环境不同导致编译出的机器码不同

图中明显看到由Java编译而来的机器码包裹在ART中,ART全称Android RunTime,即安卓运行环境,跟虚拟机差不多是一个意思。而C语言所在的运行环境不在ART中。

RunTime提供了基本的输入输出或是内存管理等支持,如果要在两个不同的RunTime中互相调用,则必然有额外开销。

举个例子,由于Java有GC(垃圾回收机制),在Java中的一个对象地址不是固定的,有可能被GC挪动了。即在ART环境中跑的机器码中的对象的地址不固定。可是C语言哪管那么多幺蛾子,C就直接问Java要一个对象的地址,但万一这个对象地址被挪动了,那就完蛋了。解决方案有两个:

把这个对象在C里再拷一份。很明显这造成了很大的开销。

告诉ART,我要用这个对象了,GC这个对象的地址你不能动!你先一边呆着去。这样相对而言开销倒是小了,但如果这个地址如果一直不能被回收的话,可能造成OOM。

(此处参考知乎@张铎在华为公布的方舟编译器到底对安卓软件生态会有多大影响?中的回答)

3. 字节码的编译模板——未针对具体APP进行优化

我们举个例子来理解编译模版,“Hello world”可以被翻译为“你好,世界”,同样也可以被翻译为“世界,你好”,这个差别就是编译模版不同导致的,

①. 统一的编译模版(vm模版)

字节码可以通过不同的编译模版被编译为机器码,而编译模版的不同将直接导致编译完后的机器码性能大相径庭。

上图的流程说明了在特殊情况下,AOT编译实则不起作用,完全是靠解释器和JIT在进行实时编译,整个编译方案退步到了Android2.2时期。

③. 聪明的ART

虽然这个问题存在,但并不是特别严重。因为ART并没有我说的那么笨。在之后应用使用过程中,ART会记录并学习用户的使用习惯(保存热点代码),然后更新针对当前APP的定制化vm模版,不断的补充热点代码,补充定制化模版。

这是不是听起来很熟悉?在手机发布大会上的宣传语“基于用户操作习惯进行学习,APP打开速度不断提高”的部分原理就是这个。

④. 最终大招,一劳永逸

其实要一劳永逸的解决这个问题思路也不难:我们只需要在吃饭前跟老板提前预定想吃啥就行,让老板先准备起来,这样等我们到了就不用等餐了。

在最新的Android9.0版本中,谷歌推出了这个类似提前预定的功能:编译系统支持在具有蓝图编译规则的原生 Android 模块上使用 Clang 的配置文件引导优化 (PGO)。

说人话:谷歌允许你在开发阶段添加一个配置文件,这个配置文件内可指定“热点代码”,当应用安装完后,ART在后台悄悄编译APP时,会优先编译配置文件中指定的“热点代码”。

虽然谷歌支持,但是这块技术对于APP开发人员而言国内资料过于缺乏,普及面不广。笔者先贴上官方链接,以及这篇博客,其中介绍的还是挺详细的。(隔壁Xcode针对PGO都有UI界面了)

三、解决思路

解决思路总结为四个字就是:华为方舟。

方舟的解决思路:

  1. 针对虚拟机问题,方舟说:我不要你这个烂虚拟机了,我们裸奔
  2. 针对JNI调用问题,方舟说:我们让Java在编译阶段跟C一样直接编译成机器码,干掉虚拟机,跟.so库直接调用,毫无JNI开销问题
  3. 针对编译模版问题,方舟说:我们支持针对不同APP进行不同的编译优化

总结一下:方舟支持在打包编译阶段针对不同APP进行不同的编译优化,然后直接打包成机器码.apk(很可能已经不叫apk了),然后直接运行。

这样看起来方舟确实解决掉了三大问题,但是,代价呢?

如果按照这个思路,方舟就肯定不止是一个编译器了,它应该还有一套自己的runtime。当然这些都是后话了。

关于方舟的实现只是大概讲了思路,但没有深入,因为一来方舟没开源,二来方舟发布会PPT营销层面更多,技术细节缺少,现在奇思妙想完全是纸上谈兵,一切还是静待开源吧。

本文标题:9102年了,还不知道Android为什么卡?
分享URL:https://www.cdcxhl.com/news46/98096.html

成都网站建设公司_创新互联,为您提供标签优化建站公司软件开发服务器托管营销型网站建设网站导航

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

网站优化排名