Android Classloader

android虚拟机和classloader简单了解

2022-01-24  本文已影响0人  nich

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;
        }
上一篇 下一篇

猜你喜欢

热点阅读