美文网首页Android开发
Android系统8.0为什么比7.0要快50%,深入虚拟机源码

Android系统8.0为什么比7.0要快50%,深入虚拟机源码

作者: momxmo | 来源:发表于2020-06-28 10:44 被阅读0次

    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。

    image.png
    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指令进行压栈操作。这样提升了 系统运行的效率!!!

    image.png
    1.6 揭秘 执行引擎源码

    执行引擎系统源码路径

    android-8.0.0_r1\art\runtime

    1.6.1 runtime文件夹下就是我们Android执行引擎
    image.png
    1.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执行的时间

    [转载自]https://mp.weixin.qq.com/s/bV5lArqn8sJkS_jch3_KOA

    相关文章

      网友评论

        本文标题:Android系统8.0为什么比7.0要快50%,深入虚拟机源码

        本文链接:https://www.haomeiwen.com/subject/toeifktx.html