在4月份,华为P30系列发布会上,华为消费者终端业务CEO余承东除了给消费者带来了万众期待的华为P30 Pro,还公布了一个全新的黑科技:华为方舟编译器。该编译器可以改善安卓应用编译效率,从原先的边解释边执行转变为全程机器码高效运行程序。称华为方舟编译器可使手机的流畅度最高提升60%,因而引起广大网友的热烈反应。
那么今天就借着华为方舟编译器一事所激起的热火朝天的大讨论。来介绍下JVM里和编译相关的两个有趣的小知识。JVM的机器码和通常所说的机器码一样吗?来看图1:
图1 目标机器码的依赖关系
图1中:
右边是C/C++源码编译成目标机器码的情况。该目标机器码编译,运行时只和目标的操作系统和相关库有关。
而Dex/Java字节码虽然也编译成目标机器码,但是它的编译和运行不仅仅依赖操作系统,还依赖具体的虚拟机实现。比如Dex字节码编译成机器码的话就依赖ART虚拟机。
很多人以为Java字节码编译成机器码后就能和那些C/C++编译得到的机器码一样无所羁绊的直接在OS上运行了,殊不知在Java字节码编译为机器码的过程中,虚拟机会添加一些必要和特殊的指令,使得得到的机器码在运行过程中实际上离不开虚拟机的管控。JVM编译的机器码叫managed code,即JVM管控的机器码。为什么要管控呢?来看一个例子:
Java虚拟机的垃圾回收器做对象标记前,往往会设置一个标志,表示自己要做对象标记了。
其他线程运行时要经常检查这个标志,发现这个标志为true时,这些线程就得等待,好让垃圾回收器能安全的做对象标记。否则的话,垃圾回收器一边做对象标记,其他线程同时又去创建对象、或更改对象间的引用关系,这将导致对象标记不准确,影响垃圾回收。
显然,程序员在代码中是不会主动加上这个检查标记的动作。实际上,这是由编译器在机器码编译过程中主动添加相关检查标记的指令来完成的。
再举一个更简单的例子,Java中内存分配new的实现和C++的new实现不同。Java中分配内存是要经手JVM的,如果内存不够,JVM还会触发垃圾回收。而C++的new则直接和OS打交道。
将Java字节码编译成机器码是因为了提高程序的运行速度。但在某些情况下,我们还得从机器码运行模式退回为解释执行模式。比如,Java语言规范中对ArrayIndexOutOfBounds(简写为AIOOB)异常抛出有明确要求,只能在运行到索引越界处才抛出。例如,一个数组长度为10,而循环次数为20,索引从0开始每次循环递增1,那么在这20次循环中,前10次都不能触发AIOOB异常,只有第11次才能触发。出现这种情况的话,虚拟机有可能从机器码执行退回到解释执行。ART 中专门提供有一个名为HDeoptimize指令,用于这种从机器码执行退化为解释执行的相关操作。来看一个能触发HDeoptimize的例子:
class Am{//注意,我对Am.java进行了修改。
static int[] arrays = null;//静态数组
//main函数,它会编译成机器码。所以,下面讨论main函数的执行时,它是以机器码方式来
//执行的
public static void main(String[] args) {
//arrays数组的大小由执行时的第一个参数决定
arrays = new int[Integer.parseInt(args[0])];
/*给arrays的前3个成员赋值。会出现两种情况:
1 如果arrays的长度大于3,则一切正常。代码依然以机器码方式执行。
2 如果arrays的长度小于3,则整个循环会以解释模式执行。 */
for(int i = 0; i <3;i++) {
arrays[i] = i;
}
return;
}
}
上述代码中,如果输入的数组长度小于3,则整个循环会退回到解释模式执行。
这里要特别说明的是,如果代码中加上try/catch的话,将不会触发HDeoptimize的处理。所以,HDeoptimize虽然是一个反优化的手段,但实际上触发它运行的几率并不大。
更多关于ART JVM的知识, 大家可尝试阅读和学习此书《深入理解Android:Java虚拟机ART》,这是一本《深入理解Android》系列最后一本压轴巨著。
《深入理解Android ART JVM》
扫码或者点击阅读原文查看书籍详情
这里要简单说明一下,这本书定价169,看起来不便宜,但按页数算的话比那些300多页定价70-80多的书反而要便宜一些。
作者是邓凡平,资深Android技术专家,从2011年开始研究和分析Android源代码,是国内Android源码分析领域的奠基人物
全书word原稿有1300多页,编撰出版后有930多页,是一本名副其实的厚作。
这本书对ART JVM相关的知识都有比较详细的源码剖析。如果涉及到一些必备的基础知识(如编译技术、ELF、垃圾回收等),也会以理论联系实际代码的形式在书中给你展现出来。
这是一本《深入理解Android》系列最后一本压轴巨著,之前出版过6本《深入理解Android》系列书籍,其中《深入理解Android 卷I》、《深入理解Android 卷II》以及《深入理解Android:Wi-Fi、NFC和GPS》这三本书已经不再出版。为了保证知识的传承,作者在CSDN网站上提供这三本书的电子版下载(https://blog.csdn.net/Innost/article/details/43342087)。
所以作为Android的开发者这是必读的书籍。以上!
扫码购买或者点击阅读原文查看书籍详情