美文网首页
Android classloader 加载机制

Android classloader 加载机制

作者: 瀚海网虫 | 来源:发表于2020-04-09 18:05 被阅读0次

    1. 有关Android 虚拟机

    1.1 Dalvik 虚拟机

    Google等厂商合作开发的Android移动设备平台的核心组成部分之一。它可以支持已转换为.dex(即“Dalvik Executable”)格式的Java应用程序的运行。

    .dex格式是专为Dalvik设计的一种压缩格式,适合内存和处理器速度有限的系统。Dalvik由Dan Bornstein编写的,名字来源于他的祖先曾经居住过的小渔村达尔维克(Dalvík),位于冰岛埃亚峡湾。

    大多数虚拟机包括JVM都是一种堆栈机器,而Dalvik虚拟机则是寄存器机。两种架构各有优劣,一般而言,基于堆栈的机器需要更多指令,而基于寄存器的机器指令更长。

    从Android 5.0版起,Android Runtime(ART)取代Dalvik成为系统内默认虚拟机。

    1.2 ART 虚拟机

    Android Runtime(缩写为ART),是一种在Android操作系统上的运行环境,由Google公司研发,并在2013年作为Android 4.4系统中的一项测试功能正式对外发布,在Android 5.0及后续Android版本中作为正式的运行时库取代了以往的Dalvik虚拟机。

    ART能够把应用程序的字节码转换为机器码,是Android所使用的一种新的虚拟机。它与Dalvik的主要不同在于:Dalvik采用的是JIT技术,而ART采用Ahead-of-time(AOT)技术。

    ART同时也改善了性能、垃圾回收(Garbage Collection)、应用程序出错以及性能分析。

    1.3 对比优缺点

    Dalvik: 应用运行需要解释执行,常用热点代码通过即时编译器(JIT)将字节码转换为机器码,运行效率低。 但是安装快。

    ART: 应用在安装时,字节码预编译(AOT)成机器码,安装慢了,但运行效率会提高,每次运行不需要重新编译,能耗更低。ART占用空间比Dalvik大(字节码变为机器码), 属于“空间换时间"。

    1.4 运行的文件格式

    • Dalvik:
      dexopt : dex 文件,运行时会进行优化 .dex---> .odex

    • ART:
      dex2aot : 先在安装时对 dex 文件执行dexopt优化,再将odex进行 AOT 编译操作,转换为OAT可执行文件(机器码)。 .dex---> .odex ---> ELF

    解释模式:
    这是个被个别大牛,吹破牛皮的名字,乍一听,不明觉厉。其实就是个简单的命令而已。 Android 7.0 以上有个优化,其实就是在.odex 的基础上,又进了,转换成了ELF。
    dex2oat –dex-file=< dex-file > –dex-location=< dex-location > 之类的,这些当前可以通过java 代码执行。 就是个简单的Process类 常规操作。实际上,不少目前的插件框架,也注意到了这一点,7.0以上,也会模拟这一步。以便跟系统保持一致。

    2. ClassLoader 机制

    2.1 双亲委派模型

    双亲委派机制的工作流程:

    1. 当前ClassLoader首先从自己已经加载的类中查询是否此类已经加载,如果已经加载则直接返回已加载的类。
      每个类加载器都有自己的加载缓存,当一个类被加载了以后就会放入缓存,下次加载时直接使用。
    2. 当前classLoader的缓存中没有找到类,委托父类加载器去加载,父类加载器采用同样的策略,首先查看自己的缓存,然后委托父类的父类去加载,一直到BootClassLoader。
    3. 当所有的父类加载器都没有加载的时候,再由当前的类加载器加载,并将其放入它自己的缓存中,以便下次有加载请求的时候直接返回。
     protected Class<?> loadClass(String name, boolean resolve)
            throws ClassNotFoundException
        {
                // First, check if the class has already been loaded
                Class<?> c = findLoadedClass(name);
                if (c == null) {
                    try {
                        if (parent != null) {
                            c = parent.loadClass(name, false);
                        } else {
                            c = findBootstrapClassOrNull(name);
                        }
                    } catch (ClassNotFoundException e) {
                        // ClassNotFoundException thrown if class not found
                        // from the non-null parent class loader
                    }
    
                    if (c == null) {
                        // If still not found, then invoke findClass in order
                        // to find the class.
                        c = findClass(name);
                    }
                }
                return c;
        }
    

    2.2 双亲委派模型好处

    一般自己写的类,由当前Classloader 加载,frameWork层之类的系统层面class,由其父容器加载。且有缓存机制,效率比较高。

    2.3 Android 中的classLoader

    • 类继承关系


      image.png

      (不严谨,仅展示开发常用的)Java 类加载器

    • ClassLooper 关系(注意不同于类继承)

    BootClassLoader : 用于加载Android Framework层class文件。

    PathClassLoader: 用于Android应用程序类加载器。可以加载指定的dex,以及jar、zip、apk中的classes.dex
    public PathClassLoader(String dexPath, String libraryPath,
    ClassLoader parent) {
    super(dexPath, null, libraryPath, parent);
    }

    DexClassLoader :加载指定的dex,以及jar、zip、apk中的classes.dex
    public DexClassLoader(String dexPath, String optimizedDirectory,
    String libraryPath, ClassLoader parent) {
    super(dexPath, new File(optimizedDirectory), libraryPath, parent);
    }
    第二个参参数,标识,对dex文件执行opt 优化后,存在的odex 目录位置。

    相关文章

      网友评论

          本文标题:Android classloader 加载机制

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