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
![](https://img.haomeiwen.com/i6909627/e50b86db5da1b680.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;
}