美文网首页Android Classloader
android虚拟机和classloader简单了解

android虚拟机和classloader简单了解

作者: nich | 来源:发表于2022-01-24 18:21 被阅读0次

    android的应用程序都是运行在dalvik/art虚拟机,每个应用都是对应一个单独的虚拟机实力,实际也算是java虚拟机,只不过java虚拟机执行的是class文件,android执行的dex文件。jvm是基于堆栈的,android是基于寄存器的

    基于栈的虚拟机,看jvm每个线程都是一个栈帧,之前jvm文章有说过

    基于寄存器的虚拟机,他是没有操作数栈的,可以堪称操作数栈和局部变量表合二为一了,所以说dalvik程序指令明显减少

    Dalvik

    dalvik虚拟机执行的是的字节码,解释执行,从2.2开始支持jit即时编译,在运行过程中热点代码进行编译和代码优化,他在应用安装的时候会执行一次优化把dex字节码文件进行优化成odex文件

    ART

    从android5.0开始,直接把自己的应用编译成机器码文件。而art是引入鱼加载机智,在安装程序的时候用自带的dex2oat进行编译,把dex翻译成机器码文件,所以安装apk的时候比较慢

    androidn的运行方式

    android混合使用aot解释执行和jit,在安装应用的时候不进行任何aot编译,在运行过程中解释执行,对经常执行的方法进行jit,然后把方法记录在profile中,当设备空闲充电的时候,对profile常用代码进行aot编译,下次直接使用

    classloader

    image.png

    看下classloader的loadclass

    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) {
                            //再通过parent加载loadclass
                            c = parent.loadClass(name, false);
                        } else {
                          //如果没有parent,使用bootclassloader
                            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;
        }
    

    这里使用双亲委托机制,在某个类进行加载器加载的时候会依次加载
    好处1.避免重复加载,爸爸加载过了儿子就不用加载了
    2.安全性,他会先加载系统的判断

    接下来看怎么加载dex

    
    
    
    @Override
        protected Class<?> findClass(String name) throws ClassNotFoundException {
            // First, check whether the class is present in our shared libraries.
            if (sharedLibraryLoaders != null) {
                for (ClassLoader loader : sharedLibraryLoaders) {
                    try {
                        return loader.loadClass(name);
                    } catch (ClassNotFoundException ignored) {
                    }
                }
            }
            // Check whether the class in question is present in the dexPath that
            // this classloader operates on.
            List<Throwable> suppressedExceptions = new ArrayList<Throwable>();
            Class c = pathList.findClass(name, suppressedExceptions);
            if (c == null) {
                ClassNotFoundException cnfe = new ClassNotFoundException(
                        "Didn't find class \"" + name + "\" on path: " + pathList);
                for (Throwable t : suppressedExceptions) {
                    cnfe.addSuppressed(t);
                }
                throw cnfe;
            }
            return c;
        }
    

    可以看到pathlist.findclass

     public DexPathList(ClassLoader definingContext, String librarySearchPath) {
            if (definingContext == null) {
                throw new NullPointerException("definingContext == null");
            }
    
            this.definingContext = definingContext;
            this.nativeLibraryDirectories = splitPaths(librarySearchPath, false);
            this.systemNativeLibraryDirectories =
                    splitPaths(System.getProperty("java.library.path"), true);
            this.nativeLibraryPathElements = makePathElements(getAllNativeLibraryDirectories());
        }
    
    
     public Class<?> findClass(String name, List<Throwable> suppressed) {
            for (Element element : dexElements) {
                Class<?> clazz = element.findClass(name, definingContext, suppressed);
                if (clazz != null) {
                    return clazz;
                }
            }
    
            if (dexElementsSuppressedExceptions != null) {
                suppressed.addAll(Arrays.asList(dexElementsSuppressedExceptions));
            }
            return null;
        }
    
    
     public Class<?> findClass(String name, ClassLoader definingContext,
                    List<Throwable> suppressed) {
                return dexFile != null ? dexFile.loadClassBinaryName(name, definingContext, suppressed)
                        : null;
            }
    

    相关文章

      网友评论

        本文标题:android虚拟机和classloader简单了解

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