JIT+解释器
JIT编译:
- C1 - 根据proflie简单编译 - quicken模式
- C2 - 根据profile - 其他编译模式
全编为什么没有混编好?
- 没考虑到热点方法,没有考虑到方法代码调用的频次和热度,没有参考profile-guide文件,存在过度编译
- 没有考虑内联、分支预测、死代码、汇编函数、公共子表达式消除、逃逸分析、锁消除、循环展开等优化方式
- 无法按照代码调用频次动态优化
Android 为什么需要解释器?
- 使用了Native缓存,内存不足时不会编译,甚至还会清理缓存
- JIT编译产生可能产生,需要依靠解释器逃逸
- Android 静态编译安装太慢
Android dex2Oat支持哪些编译?
- secondary dex编译
支持android 5.0之后的机型,5.0之前的机型可以参考BoostMutliDex去加载进行优化
- dex编译
- 布局编译(android Q才支持的)
public class ViewCompiler {
private final Object mInstallLock;
@GuardedBy("mInstallLock")
private final Installer mInstaller;
public ViewCompiler(Object installLock, Installer installer) {
mInstallLock = installLock;
mInstaller = installer;
}
public boolean compileLayouts(PackageParser.Package pkg) {
try {
final String packageName = pkg.packageName;
final String apkPath = pkg.baseCodePath;
final ApplicationInfo appInfo = pkg.applicationInfo;
final String outDexFile = appInfo.dataDir + "/code_cache/compiled_view.dex";
Log.i("PackageManager", "Compiling layouts in " + packageName + " (" + apkPath +
") to " + outDexFile);
long callingId = Binder.clearCallingIdentity();
try {
synchronized (mInstallLock) {
return mInstaller.compileLayouts(apkPath, packageName, outDexFile,
appInfo.uid);
}
} finally {
Binder.restoreCallingIdentity(callingId);
}
} catch (Throwable e) {
Log.e("PackageManager", "Failed to compile layouts", e);
return false;
}
}
}
BackgroundDexOptService如何触发?
PMS或bg-dex-opt
这个在android Q中已经没法实现了,只能使用shell或者system账号
profile文件获取?
PackageDexOptimizer
String profileName = ArtManager.getProfileName(i == 0 ? null : pkg.splitNames[i - 1]);
如何让编译器编译插件活着补丁?
在运行阶段,触发后台编译
问题
1、无法优化插件和补丁
2、热更新还存在静态编译引用问题,因此需要注入自己的ClassLoader ,防止加载旧代码