AOT 和 JIT IL2CPP和Mono CLR ILRuntime热更新原理

Posted 浪里个浪mvp

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AOT 和 JIT IL2CPP和Mono CLR ILRuntime热更新原理相关的知识,希望对你有一定的参考价值。

AOT 和 JIT

字面意思:JIT:Just In Time AOT:Ahead of Time

区别: 主要区别在于是否在“运行时”进行编译.

优劣: AOT优点: 1.在程序运行前编译,可以避免在运行时的编译性能消耗和内存消耗. 2.可以在程序运行初期就达到最高性能. 3.可以显著的加快程序的启动. AOT缺点: 1.在程序运行前编译会使程序安装的时间增加. 2.牺牲Java的一致性. 3.将提前编译的内容保存会占用更多的外存.

JIT优点: 1.可以根据当前硬件情况实时编译生成最优机器指令(ps:AOT也可以做到,在用户使用是使用字节码根据机器情况在做一次编译). 2.可以根据当前程序的运行情况生成最优的机器指令序列. 3.当程序需要支持动态链接时,只能使用JIT. 4.可以根据进程中内存的实际情况调整代码,使内存能够更充分的利用. JIT缺点: 1.编译需要占用运行时资源,会导致进程卡顿. 2.由于编译时间需要占用运行时间,对于某些代码的编译优化不能完全支持,需要在程序流畅和编译时间之间做权衡. 3.在编译准备和识别频繁使用的方法需要占用时间,使得初始编译不能达到最高性能.

IL2CPP【AOT编译】

CLR(公共语言运行库)在运行期管理程序的执行:主要包含:内存管理、代码安全验证、代码执行、垃圾收集

IL2CPP相比Mono的优劣

unity中的AOT、JIT、IL2CPP、Mono_勤学者闯天涯的博客-CSDN博客_aot unity

Mono interpreter 介绍

New. NET interpreter – Mono has arrived | Develop Paper

框架:https://github.com/focus-creative-games/huatuo

huatuo框架在Mono interpreter技术启发下实现了AOT+interpreter形式

从底层彻底支持了热更新dll。

误区

ios 只支持AOT模式的,Mono 可提供AOT模式和 JIT模式上的,所以在IOS上是可以用MONO的,不过需要选用MONO的AOT模式,并不是在ios平台上必须要选中IL2cpp

ILRuntime热更新原理是什么?

原文 ILRuntime热更新原理是什么? -- UWA问答:帮助开发者找到更好的答案

请问ILRuntime热更新的底层原理是什么?能否这样理解:常规的CLR需要JIT编译方法为机器语言后存入内存,再调用该内存执行,所以需要内存执行权限,ios封了内存的执行权限所以没法JIT只能AOT。ILRuntime实现了对于IL的解释执行,解释执行是逐句直接调用机器语言,跳过了内存执行这个步骤,所以实现了热更?

不是逐句调用机器语言,而是逐句解析il指令,你用ildasm查看 一个dll内容,会发现就是许多的类汇编的指令结构。查看ilruntime源码你会发现,内部有一个很大的switch/case结构,就是针对基本上每一条il指令码进行解释,同时维护一个stackframe用于模拟cpu的函数调用的基本操作进行辅助解释。
ilruntime中解释热更dll中的自定义类实例,在框架层这边都是对应的同一个warper,即iltyeinstance。iltyeinstance会知道最终被调用方法的il指令内容,如果调用,则就是switch逐句去解析这个方法的il码,这里面会发现没有什么执行权限的问题,简单理解为读取一个普通文件,然后解析文件内容。如果是反射处理这种情形,那就是真实的构建出一个新的类型,然后调用新类型的方法,这倒是会涉及到内存权限问题。
所以:ilruntime整个过程中没有涉及到新类型的生成,都是iltypeinstance,没有涉及到新类型的内存执行权限的问题。

一家之言 

理解Java的JIT和AOT

1. JIT和AOT是什么?

JIT是Just-In-Time的首字母缩写,指程序运行期间发生的编译行为。

  • JIT多伴随解释器,因为解释型语言是按行解释执行,JIT将“常用”功能编译为机器码,需要时直接执行,减少解释时间;
  • 例如:Python(pypy),新版Javascript、Ruby、Php解释器;

AOT是Ahead-Of-Time的首字母缩写,指程序运行之前发生的编译行为。

  • 对于编译型语言,AOT啥也不是,本身就是先编译后执行,但对于解释型语言,AOT提前“预见”热点功能,并编译为机器码,同样减少解释时间;
  • 例如:C,C++,Rust,Go,Java AOT;

2. Java的JIT和AOT是什么?

下面两张图来自Mark Stoodly的分享,清晰解释了Java JIT和AOT的位置和作用。可以看出JIT是在代码执行中“理解”代码的过程,而AOT是在代码执行前“预见”代码的过程。


JIT位置


AOT位置

3. Java的JIT和AOT如何执行?

下图是简化的JVM执行流程图,包含三个操作。


1. 第一个操作是JVM的标准动作:JVM解释器(一行一行的)读取字节码并执行。

2. 第二个操作是Java JIT:从字节码中“寻找”热点代码编译为机器码,放入代码缓存,下次调用跳过解释器,直接执行该机器码。

  • JIT包括C1和C2两种编译器,目的相同但深度不同;
  • C1编译器:寻找高频(>10000次)字节码编译为机器码。C1速度快但优化有限,也叫客户端优化;
  • C2编译器:通过code profiling数据,定位code path进而寻找热点代码(Hot Spot,名字很熟悉是不是?),对这部分字节码进行深度优化,编译为机器码。C2速度慢但深度优化,执行速度快,也叫服务器端优化;
  • C2包含二十多项优化,包括 死代码(删除没有使用的代码)、 逃逸分析(方法中创建但没有返回的对象,将它从堆移到栈)、 方法对齐(将大量小方法移到到调用方法中)、 锁删除(如果只有一个线程使用锁,删除该锁)、 Null检查(如果对象永远不为null,删除判空);
  • C1和C2都在后台运行,只是时间不同。当字节码解释时C1开始运行,优化后替换字节码调用;当C1代码运行时C2开始运行,优化后替换C1代码调用;
  • Java 7及以前可以通过参数--client或--server自定义C1或C2,Java 8默认启用C1和C2;

3. 第三个操作是Java AOT:先将部分字节码(class文件/文件夹/JAR包)提前编译为机器代码库,然后再启动程序,减少字节码解释。

  • AOT可以加快代码执行,但缺点也很明显。因为Java字节码独立于平台,但机器码依赖平台架构,且目前AOT支持的平台有限。同一份代码,如果要在ARM和X86运行,则需要AOT两份;
  • jaotc是JDK 9引入的实验性命令,在Oracle JDK 16已经删除,有些JDK仍存在;

javac HelloWorld.javajaotc —output LibHelloWorld.so —class-name HelloWorld.classjava —XX:AOTLibrary=./LibHelloWorld.so HelloWorld


最后,本文在理解JIT和AOT的思想,它仍在演进和开发中,并且不同JDK发行版实现也不同。 

以上是关于AOT 和 JIT IL2CPP和Mono CLR ILRuntime热更新原理的主要内容,如果未能解决你的问题,请参考以下文章

JVM 虚拟机 AOT 和 JIT 即时编译

JVM 虚拟机 AOT 和 JIT 即时编译

理解Java的JIT和AOT

JIT和AOT编译详解

ART中AOT和JIT编译器的区别

IL2CPP 与 Mono2x 和 Android 部署