Android Q 是谷歌公司在2019年推出的新一代操作系统 ,也被称为Android10.0 。
众多手机品牌厂商也都在已经更新适配 Android 10.0 系统 。
Android10.0在功能上只是增加了暗黑模式和一些简单的UI更改,Android9.0 呢也只是增加了隐私的安全性,在最近两个版本中都没有在性能上明显的提升。真正在Android运行性能提升时发生在Android8.0。
在上一个版本基础上优化了50%的速度,有没有小伙伴想知道这50%是怎么来的呢?
目前Android8.0的源码已经开源,并提供给广大开发者下载,接下来的内容 我们就一起围绕这50%的提升率,从Android8.0找到答案吧!
1.1 想要知道为什么Android8.0做了什么,我们得了解Android虚拟机的内存图
image.png堆区: 只存放类对象,实例化的数据放在堆区;堆区的数据放在主内存
方法区:又叫静态存储区,存放class文件和静态数据,全局变量;方法区的数据在主内存
栈区:存放方法局部变量,方法,线程不共享; 栈区的数据在高速缓冲区
执行引擎:将方法区中 对应方法的arm指令集 加载到栈区,而栈区存在于高速缓冲区中,cpu是直接
从高速缓冲区取arm指令,一条一条执行。执行引擎就像一个中介,方法对应的arm指令 相当于交易的物品
1.2 什么是主内存,什么是高速缓冲区呢?
我们都知道 cpu执行是非常快的,而主内存执行起来会慢很多,这会影响cpu的执行效率。在Android手机cpu中加了一个高速缓冲区(在pc上叫三级缓存),协调cpu与主内存之间的存取数据速度。
高速缓冲区容量比较小,一般只有8M,12M。
1.3 我们一起来看看Android 方法执行的原理
有这样一段 方法很简单,只是做了new Singleton()对象操作,并将对象返回出去
public Singleton getInstance() {
Singleton instance = new Singleton();
return instance;
}
一个java方法 被翻译成arm指令
0000: new-instance v0, Singleton // type@0000
0002: invoke-direct {v0}, Singleton.<init>:()V // method@0000
0005: return-object v0
我们不用去管arm指令 是怎么来的,每一句代码起什么作用
我们重点是 观察 方法对应的arm指令 在主内存到cpu的发生了什么
image.png
备注:方法是属于class类的,class类存在于方法区中,所以方法对应的 arm指令集也是在方法区中,
1.4 执行过程:
1.第一步 执行引擎将 方法对应的arm指令集 加载到执行引擎
2.执行引擎将arm指令集,封装好后进行压栈操作,压栈到高速缓冲区中
3.cpu从高速缓冲区中取到一条一条指令,进行执行
1.5 为什么Android8.0能比7.0快50%呢? 就在执行引擎上!!!!
Google工程师对执行引擎进行了大范围修改,这些修改内容,对Android开发者来说是不可见的。但是能大大加快程序运行速度,如8.0中的热放方法缓存,Framework层大量的 系统函数被标记了@FastNative注解
Fastnative注解意义: 经过FastNative标记的方法,系统会自动将方法执行的结果缓存到内存中,下次调用时,执行引擎不在对方法对应的arm指令进行压栈操作。这样提升了 系统运行的效率!!!
1.6 揭秘 执行引擎源码
执行引擎系统源码路径
android-8.0.0_r1\art\runtime
1.6.1 runtime文件夹下就是我们Android执行引擎
image.png1.6.2 Android8.0中 执行引擎中如何处理经过FastNative修饰的热方法
在artmethod.h头文件中 有这样一段声明 小伙伴可以亲自打开看一看,这样就能理解为什么Android8.0要比上一个版本快这么多原因了!
class ArtMethod {
// The hotness we measure for this method. Managed by the interpreter. Not atomic, as we allow
// 通过注释可以知道 该变量时标记经过 java方法运行的频率,
uint16_t hotness_count_;
struct PtrSizedFields {
// Short cuts to declaring_class_->dex_cache_ member for fast compiled code access.
//通过google给我们的注释 可以知道,缓存一个方法对应的arm指令,快速的得到结果
ArtMethod** dex_cache_resolved_methods_;
//上面方法执行的结果 数据缓存在data_ 变量中,下次执行经过@FastNative修饰的java方法时,直接取出数据
void* data_;
//arm指令在内存中的地址,快速的定位到arm指令
void* entry_point_from_quick_compiled_code_;
} ptr_sized_fields_;
image.png
总结:
在Android8.0中 改动了虚拟机中程序执行引擎的源码!将频率高的方法执行的结果提前缓存在内存中,
以空间换时间的方式,提升Android执行速度,以前一个java方法执行 需要加载指令,压栈指令,cpu逐行读取指令,在8.0中 ,都不需要了,直接从上一次执行的结果中取。减少cpu执行的时间
网友评论