ILRuntime

关注
义项:Unity热更新框架
ILRuntime

ILRuntime是面向以C#为主要开发语言的运行环境(例如Unity)提供的一个纯C#实现的IL运行时(IL Intepreter Runtime),它通过解释执行热更新程序集里的中间语言指令,使代码逻辑可以在不重新打包应用的前提下更新,从而绕开iOS等平台不允许在运行时生成机器码的限制[1]。使用它的项目可以继续用同一套C#语言与工具链开发热更逻辑,无需额外抽象出脚本API[2][3]。

百科 图文
目录
  1. 定义
  2. 原理
  3. 发展历程
  4. 应用
  5. 局限
  6. 参见

定义

ILRuntime是一个用C#编写的中间语言解释器运行时,主要服务于使用Unity等C#平台的工程。它的作用是在不重新发布安装包的情况下更新程序中的业务逻辑,属于代码热更新方案的一种[1]。项目在代码托管平台以开源形式发布,仓库中包含运行时代码、测试工程与Unity示例工程[3][1]。

与把逻辑改写为Lua脚本的方案相比,ILRuntime的差别在于热更代码仍然用C#编写和编译,团队不必同时维护两套语言技能,第三方的C#插件也大多可以直接使用[4]。其定位是让原本无法在运行时生成机器码的设备也能执行可替换的程序集,因此常与Unity的IL2CPP后端配合使用[5]。

原理

运行时借助Mono.Cecil库读取热更程序集的文件结构,取得其中类型、方法等元数据,并拿到方法对应的MSIL字节码,再由内置的解释执行虚拟机和即时编译模块逐条执行这些指令,从而让DLL中的代码真正跑起来[6]。由于这套机制输出的是自定义的虚拟指令集而非真实硬件指令,所以它不触碰平台对动态代码生成的安全限制[7]。

为降低资源开销,ILRuntime实现了自己的类型表示与求值栈结构,以减少装箱拆箱以及由此产生的托管堆分配[6]。热更代码与主工程代码分处两个程序集,跨过边界调用时会引入额外开销,因此框架提供了CLR绑定与CLR重定向两项机制:前者为常用外部类型生成静态调用代码,后者在解释器遇到指定外部方法时把调用转交给预先注册的实现[6][8]。

2.0版加入了寄存器模式,它先用自带的即时编译器把原始MSIL转换成基于寄存器的自定义指令集再执行。该模式针对循环、数学运算和属性访问等场景有效,对主要由调用外部接口构成的方法则可能没有收益甚至略慢;开启方式包括在AppDomain构造时指定JITOnDemand、JITImmediately等模式,或对个别类与方法单独标注[7][9]。

发展历程

ILRuntime由Ourpalm发起并开源维护,其早期定位即为在无法进行即时编译的环境上提供纯C#的IL运行时[1][3]。早期版本已经具备跨域继承、泛型支持和真机源码级调试等能力,调试插件最初只支持Visual Studio 2015 Update 3及以上版本,后续扩展到Visual Studio 2017、2019和2022[3][10]。

1.3.0版引入值类型绑定机制,用于消除外部值类型参与运算时的装箱拆箱开销[6]。2.0.0版加入寄存器运行模式,并对传统模式的执行效率做了提升,同时修正了热更代码中finally块、yield return与async/await等并发与异常处理相关的问题[9]。公开仓库的版本记录显示,2.1.0版于2022年10月发布,项目累计有数十名贡献者参与[1]。

随着Unity生态演进,社区也出现了HybridCLR等原生C#热更新方案,与ILRuntime形成同类技术路线的对比与并存[11][12]。

应用

该框架的典型用途是游戏客户端的代码热更新:把需要频繁调整的业务逻辑单独编译成DLL,随资源一起下发,客户端启动或运行时再加载对应程序集并调用其中的入口方法,从而在不上架新版安装包的情况下修复缺陷或调整功能[3][10]。公开资料提到,采用该方案的项目涵盖大型多人在线、策略、休闲与棋牌等类型[4]。

在资源管理上,热更DLL通常与其他资源一同打入AssetBundle,或放入对象存储与内容分发网络,由客户端按版本号或标记下载后交给ILRuntime加载[10][3]。框架对Json序列化库LitJson做了集成,便于热更代码中直接使用数据转换功能[6]。此外也存在以ILRuntime为底层实现的热修复与脚本化框架项目[12]。

局限

热更部分的代码不能随意挂载到场景对象上。实践中通常要求可热更的类不继承MonoBehaviour,将涉及Unity组件生命周期与消息转发的部分留在主工程中,以规避解释执行与引擎对象模型之间的冲突[4][2]。跨域继承也有约束,一个类同时实现多个外部接口时容易出现难以预期的问题,因此建议先在主工程侧准备基类再由热更代码继承[6]。

性能方面,解释执行天然慢于编译后的原生代码,使用IL2CPP时整体执行效率会明显低于Mono后端,纯数值计算场景的表现也可能不及Lua方案,计算密集的逻辑更适合放在不可热更的部分;官方因此建议对热点方法开启寄存器模式或做绑定优化[4][7]。跨域调用与反射相关的代码容易产生额外的内存分配,官方给出通过CLR绑定减少反射调用、避免在热更代码中使用foreach等优化建议[6]。

此外,涉及反射、复杂语言特性组合以及async/await等场景的稳定性问题在早期版本中较为集中,部分高级特性在旧版本上的支持并不完备[4][9]。调试插件在早期阶段能力有限,断点后仅能查看基础类型的局部变量与参数值[3]。

参见

  • Unity —— ILRuntime最主要的运行环境,多数使用场景是Unity开发的游戏客户端。

  • Mono.Cecil —— ILRuntime读取热更程序集元数据与IL指令所依赖的库。

  • HybridCLR —— 同属C#热更新方向,采用与解释执行不同的实现思路。

  • XLua —— 以Lua脚本实现Unity热更新的方案,常与ILRuntime并列比较。

  • IL2CPP —— Unity的编译后端,ILRuntime常与其配合用于iOS等平台。

参考资料

  1. ILRuntime [引用日期2026-10-14]
  2. ILRuntime与代码热更新框架的搭建技巧 | Unity 中文课堂 [引用日期2026-10-14]
  3. ILRuntime [引用日期2026-10-14]
  4. 必读!ILRuntime来实现热更新的优与劣! [引用日期2026-10-14]
  5. 概念说明_Unity热更新之ILRuntime-CSDN在线视频培训 [引用日期2026-10-14]
  6. ILRuntime热更新 - //HotFix_Project [引用日期2026-10-14]
  7. 寄存器模式 [引用日期2026-10-14]
  8. ILRuntime的性能优化 [引用日期2026-10-14]
  9. 更新记录 [引用日期2026-10-14]
  10. CDN + ILRuntime [引用日期2026-10-14]
  11. 热更新有什么推荐方案吗? [引用日期2026-10-14]
  12. ILRuntime [引用日期2026-10-14]
词条评价
词条统计

浏览次数:2 次

阅读量:0 次 · 阅读完成量:0 次

最近更新:2026-10-13T21:09:21Z

历史版本

本条目引用的词条
Unity Mono.Cecil HybridCLR XLua IL2CPP