.NET平台系列7 .NET Core 体系结构详解

- 运行时
.NET Core 中包含2种运行时:CoreCLR 与 Native RunTime。CoreCLR 是一个开源的JIT运行时,它将代码编译成中间语言(IL),在终端机器运行时再转换成机器码。NativeRuntime 将 C# 、F#或VB代码直接转换为原生机器码直接运行。
- BCL
BCL 即 Base Classlibrary 基础类,例如 File、System、Console、XML、ADO.NET、日期时间等类库。
- App Model
.NET Core 是由许多项目所组成,除了基本的类库(Core FX) 之外,也包含采用 RyuJIT 编译的运行平台 Core CLR、编译器平台.NET Compiler Platform、采用 AOT 编译技术运行最优化的包 Core RT (.NET Core Runtime),以及跨平台的 MSIL 编译器 LLILC (LLVM-based MSIL Compiler) 等项目。

【底层】编译器
- Roslyn
.NET Compiler Platform (项目代码为 Roslyn) s是一个开源的跨平台源代码编译器。它是将 .NET平台的编译架构标准化的平台,它可提供程序管理工具 (如集成开发环境) 相当多的情报,用以发展有助于编写程序与管理程序结构所需要的功能,例如类型信息、语法结构、参考链接、语义、编译器、自动化、错误回报等等功能,只要是遵循 CLI 标准的编程语言,都可以利用 .NET Compiler Platform 实现出编译器,让程序管理工具能实现如语法提示、语法自动完成、关键字高亮等可视化能力。
.NET Compiler Platform 可同时支持 .NET Framework 4.6 以上版本,.NET Core 也原生支持。
- RyuJIT
RyuJIT 是微软发展的新式即时编译器 (Just-in-Time Compiler),用以替换现有的 .NET Framework 的 JIT 以及 JIT64 即地编译器,依据微软公布的测试报告,RyuJIT 的性能较前一代的 JIT 提升约 25%,并支持SIMD(Single Instruction, Multiple Data) 的技术。RyuJIT 同时应用于 .NET Framework 4.6 以及 .NET Core 。
最主要的是它实现了AMD64的架构。
- Core CLR
Core CLR 移植 .NET Framework 的 CLR 的功能,包含核心程序库 mscorlib、JIT 编译器、垃圾收集器 (GC) 以及其他运行 MSIL 所需要的运行期环境。核心功能包括:内存管理、程序集加载、安全性、异常、线程管理等。
- Core RT
Core RT 是以AOT (Ahead-of-time) 编译方式为主的核心功能,在 .NET Core 内称为 Core RT,在 UWP 则是称为 .NET Native。
Core RT 会在建造时期 (非运行期) 在编译时将 MSIL 转换成平台本地的机器码,以获取较短的引导时间 (JIT 采用的是运行时期编译,使得引导时间拉长),以及内存用量减少的优点。Core RT 会在不同的平台使用不同的 AOT 技术:
· Windows 上使用的是 .NET Native。
· macOS 与 Linux 上使用的是 LLILC (同时支持 JIT 和 AOT)。
CoreRT 提供了一套AOT 的机制,可以将.NET Core程序编译成原生代码,不依赖 .NET 运行时而运行在宿主机器上。
除此之外两个运行时大部分功能代码是共享的,比如GC。AOT的优化带来不少好处:
- 编译后生成一个单文件,包含所有的依赖,包括 CoreRT,无需安装Framework或.NET Core。
- 启动时是机器码,不需要生成机器码,也不要加载JIT编译器。
- 可以使用其他优化编译器,包括 LLILC ,IL to CPP。
CoreRT有两个方式生成机器码,第一个使用是直接编译IL成机器码。默认情况下,RyuJIT 作为一个 AOT 编译器将IL编译成机器码。另一个方式是将C#代码编译成C++代码,然后调用对应平台的C++编译器优化编译成机器码。
- LLILC
LLILC (LLVM-based MSILCompiler,英文发音为 "lilac") 是 .NET Core 在非 Windows 平台的 MSIL 编译器 ,基于 ECMA-335 (Common Language Infrastructure) 的标准将 MSIL 编译成原生码运行,适用于可运行 LLVM 的操作系统,例如 macOS与 Linux 操作系统。LLILC 同时支持 JIT (内含 RyuJIT 的实现) 以及 AOT (未来将开始支持) 的编译方式。
【中间层】核心类库
- CoreFX(.NET Core Libraries)
CoreFX主要包含数个公共库,例如 System.Collections, System.IO, System.Xml等。CoreFX是 .NET Standard Library 的实现,同样的.NET Framework 4.6.3也是基于.NET Standard Library的实现。它们目前都是基于.NET Standard Library1.6版本,具体见下表:

开源地址:https://github.com/dotnet/corefxlab
【应用层】开发框架
开发框架是开发基于UI应用的框架集,包括了ASP.NET Core(用于创建Web App),和 UWP(用于创建Windows10 App) 等。
Roslyn编译器用于将 C#、F#或VB.NET 代码编译为程序集(Assembly),它的编译过程是一个管道式的处理过程,一共包含4个步骤,具体过程见下图。
(1)Parser(解析)
根据语法对源代码进行解析。
(2) Declaration(声明)
为代码生成元数据(metadata),元数据是一个数据表的集合,描述了在当前代码中定义的数据类型和成员,同时也描述了引用的类型及成员。
(3)Bind(绑定)
将生成的IL代码与描述它的元数据绑定在一起,生成托管模块(managed module)。
(4)Emit(生成)
将一个或多个托管模块合并生成程序集(assembly)。
从上图可以看到使用JIT编译和使用AOT编译源代码并运行程序是两种不同的流程。
如果使用JIT编译器部署程序时只需要将程序打包为IL的assemblies,在方法第一次执行前编译器将IL编译为目标机机器码(Native code),而AOT编译会在编译时将源代码直接编译为目标机机器码。
AOT将源代码编译为机器码,拥有如下特性:
(1)用静态代码替换反射,例如如果一个值类型(value type)没有重写 ValueType.Equals 的equals()方法,默认情况判断相等,会使用反射找到FiledInfo以确定Type是否相等,然后再比较Value是否相等。而在AOT编译中由于替换了反射因此只能比较Value是否相等。
(2)依赖的第三方类库以及.NET Libraries均打包至最终编译的程序中。
(3)打包后的程序运行在一个精简版的运行时上(CoreRT)主要包含垃圾回收器,而运行时也会打包在app文件中。
(4)虽然编译时会替换反射代码,但遇动态反射代码无能为力,运行时若遇动态反射调用则会因找不到对应的元数据及实现而抛出异常。解决办法是编译前配置运行时指令文件(Runtime directive file)指定需要用到的程序集。
参考:https://docs.microsoft.com/zh-cn/dotnet/standard/components
https://docs.microsoft.com/zh-cn/dotnet/standard/clr
https://www.cnblogs.com/xuanhai/p/6691647.html
.NET平台系列7 .NET Core 体系结构详解的更多相关文章
- .NET6 平台系列2 .NET Framework框架详解
系列目录 [已更新最新开发文章,点击查看详细] 什么是 .NET Framework? .NET Framework 是 Windows 的托管执行环境,可为其运行的应用提供各种服务. 它包括 ...
- .NET 平台系列6 .NET Core 发展历程
系列目录 [已更新最新开发文章,点击查看详细] 在我的上一篇博客<.NET平台系列5 .NET Core 简介>中主要介绍了.NETCore的基本情况,主要包括.NET跨平台的缘由 ...
- net core 中间件详解及项目实战
net core 中间件详解及项目实战 前言 在上篇文章主要介绍了DotNetCore项目状况,本篇文章是我们在开发自己的项目中实际使用的,比较贴合实际应用,算是对中间件的一个深入使用了,不是简单的H ...
- 【转】段错误调试神器 - Core Dump详解
from:http://www.embeddedlinux.org.cn/html/jishuzixun/201307/08-2594.html 段错误调试神器 - Core Dump详解 来源:互联 ...
- 深入浅出Mybatis系列(四)---配置详解之typeAliases别名(mybatis源码篇)
上篇文章<深入浅出Mybatis系列(三)---配置详解之properties与environments(mybatis源码篇)> 介绍了properties与environments, ...
- Android Studio系列教程五--Gradle命令详解与导入第三方包
Android Studio系列教程五--Gradle命令详解与导入第三方包 2015 年 01 月 05 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://s ...
- 构建安全的Xml Web Service系列之wse之错误代码详解
原文:构建安全的Xml Web Service系列之wse之错误代码详解 WSE3.0现在还没有中文版的可以下载,使用英文版的过程中,难免会遇到各种各样的错误,而面对一堆毫无头绪的错误异常,常常会感到 ...
- [js高手之路] es6系列教程 - 对象功能扩展详解
第一:字面量对象的方法,支持缩写形式 //es6之前,这么写 var User = { name : 'ghostwu', showName : function(){ return this.nam ...
- Linux内核异常处理体系结构详解(一)【转】
转自:http://www.techbulo.com/1841.html 2015年11月30日 ⁄ 基础知识 ⁄ 共 6653字 ⁄ 字号 小 中 大 ⁄ Linux内核异常处理体系结构详解(一)已 ...
随机推荐
- 一种借助POI粗略的标注城市也许重要的区域的方法
第一部分 很久以前,我住在村子里,因为村子小,所以对村子的一草一木都很熟悉,在熟悉的环境里就很有安全感. 后来我到了大城市,却发现城市太大了,一辈子都熟悉不完. 这个城市的绝大部分地方我都没有去过,就 ...
- 依赖反转原则DIP 与使用了Repository模式的asp.net core项目结构
DIP 依赖反转原则 Dependency Inversion Principle 的定义如下: 高级别的模块不应该依赖于低级别的模块, 他们都应该依赖于抽象. 假设Controller依赖于Repo ...
- 一文搞懂如何实现 Go 超时控制
为什么需要超时控制? 请求时间过长,用户侧可能已经离开本页面了,服务端还在消耗资源处理,得到的结果没有意义 过长时间的服务端处理会占用过多资源,导致并发能力下降,甚至出现不可用事故 Go 超时控制必要 ...
- Android 之 ToolBar 踩坑笔记
写在前面 •前言 这两天,学完了 Fragment 的基础知识,正准备跟着<第一行代码>学习制作一个简易版的新闻应用: 嘀嘀嘀~~~ 一声消息传来,像往常一样,打开 QQ,当我看到 QQ ...
- Spring Cloud:面向应用层的云架构解决方案
Spring Cloud:面向应用层的云架构解决方案 上期文章我们介绍了混合云,以及在实际操作中我们常见的几种混合云模式.今天我们来聊一聊Spring Cloud如何解决应用层的云架构问题. 对于Sp ...
- C++并发与多线程学习笔记--基本概念和实现
基本概念 并发 可执行程序.进程.线程 学习心得 并发的实现方法 多进程并发 多线程并发 总结 C++标准库 基本概念 (并发.进程.线程)区分C++初级编程和中高级编程 并发 两个或者更多的任务同时 ...
- KubeEdge EdgeMesh设计原理
EdgeMesh主要用来做边缘侧微服务的互访. ServiceMesh service mesh是一个服务网格的概念.在传统的架构里面都是通过像Dubbo来进行服务治理,服务治理的程序和我们应用程序强 ...
- 利用卷影拷贝服务提取ntds.dit
0x01 前言 通常情况下,即使拥有管理员权限,也无法读取域控制器中的C:\Windows\NTDS\ntds.dit文件.那么什么是ntds.dit呢? ntds.dit文件是一个数据库,用于存储A ...
- Salesforce学习之路(六)利用Visualforce Page实现页面的动态刷新功能
Visualforce是一个Web开发框架,允许开发人员构建可以在Lightning平台上本地托管的自定义用户界面.其框架包含:前端的界面设计,使用的类似于HTML的标记语言:以及后端的控制器,使用类 ...
- 基本dos命令
Dos命令 打开cmd方法 开始---windows系统---命令提示符 win键 + R键 输入cmd --- 回车 按住Shift键---右击任意文件夹-----单击在此处打开PowerShell ...