Mono运行时总结

5 篇文章 0 订阅

Mono运行时

1、两种编译器:

(1)        C#编译器mcs(Mono2.11版本以上):将C#编译为ECMA CIL标准的byte code;

(2)        Mono运行时中的编译器:将CIL的byte code转移为原生码。

2、三种转译方式:

(1)        即时编译(Just-in-time,JIT):程序运行过程中,将CIL的byte code转译为目标平台的原生码。

整体流程:

a.编译器将游戏脚本编译为托管模块(PE文件),除了编译生成CIL码外,编译器还会在托管模块中生成metadata元数据,元数据主要用来描述该模块定义了什么。

b.编译器默认将生成的托管模块转换为程序集(Assembly,通常是一些以Assembly开头的dll文件),程序集是由一个或多个模块\资源文件的逻辑性分组。程序集有一个数据块用来存放它下面所有托管模块的元数据表,即manifest清单,其内容主要包括:构成程序集的文件、程序集中文件所实现的公开导出的类型,以及和程序集相关联的资源或数据文件。程序集是重用、安全性以及版本控制的最小单元。

c.使用JIT编译执行程序集代码。首先将Mono运行时加载进入内存,目标系统创建进程,然后进程的主线程调用方法初始化Mono运行时并加载所需的程序集,之后调用入口方法。Mono运行时分配内部数据结构,在这个结构中,类型定义的方法都有一个记录项,每个记录项都有一个对应的地址,通过地址可找到方法的实现,该数据结构进行初始化时,Mono运行时会将每一个记录项都设置成包含在Mono运行时内部的一个叫作JITCompiler的未编档函数,之后Mono运行时通过调用JITCompiler函数进行JIT编译过程。

JIT运行新代码就是将生成的机器码映射到内存中,然后执行。由于IOS封存了内存(或者堆)的可执行权限,相当于变相的封锁了JIT这种编译方式。

(2)        提前编译(Ahead-of-time,AOT):程序运行之前,将.exe或.dll文件中的CIL的byte code部分转译为目标平台的原生码并且存储,程序运行中仍有部分CIL的byte code需要JIT编译。

(3)        完全静态编译(Full-ahead-of-time,Full-AOT):程序运行前,将所有源码编译成目标平台的原生码。

Full-AOT的限制:a.不支持泛型虚方法;b.不支持对泛型类的P\Invoke;c.不能使用反射中的Property.SetInfo给非空类型赋值;d.值类型作为Dictionary的Key时会有问题,实际上实现了IEquatable<T>的类型都会有问题;e.由于不允许动态生成代码,因此无法使用System.Reflection.Emit,无法动态创建类型,无法使用DLR及基于DLR的任何语言。

3、垃圾回收器(GC,管理的是Mono的托管堆,引用类型会被分配在托管堆上)

(1)贝姆垃圾收集器(Boehm):基于Mark\Sweep,无分代\并行;执行时所有线程阻塞;每次标记都会扫描访问到所有可到达的对象(穷举搜索垃圾)。所有这种方式极有可能以一定时间间隔造成帧率下降,影响玩家体验;

(2)分代收集(genetational collector,Mono2.8版本后才有)

GC触发:(1)堆内存不足,自动调用GC;(2)手动调用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值