俺的回收站

架构分析 解释编译原理
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

CLI 架构(Architecture)

Posted on 2006-12-15 16:44  Riceball LEE  阅读(2354)  评论(5编辑  收藏  举报
通用语言基础组织 Common Language Infrastructure (CLI) 提供执行代码以及执行环境(the Virtual Execution System, or VES)的规范.

CLI 架构包括了以下的内容:
 *  虚拟机设计
    * 线程
    * 动态绑定 classes, assemblies, and application domains.
    * 分布式文件加载
    * 保护机制
    * CTS(Common Type System) - Self-describing type system
    * Cross assembly method/member function invocation
    * Side-by-side execution (simultaneous support for separate versions of the same component)
    * Managed and unmanaged code interoperability(协同工作能力)
 *  源语言独立 Source language independence
 *  软件组件版本管理 Software component version management
 *  软件分发模式 The software deployment model
 *  安全机制 Security mechanisms that address the mechanism that allows such general distribution of mobile code
 *  CLI 通讯机制 CLI communication mechanisms

== 模块(Module) ==
模块(Module)类似于以前的单元,用于分割不同的类和类型,以及资源(resource, 资源记录就是字符串,图象以及其它数据,他们只在需要的时候才会被调入内存)。类型的Meta信息也是模块的一部分。
CLR 的程序集是由模块构成的,CLR 模块是一种流数据(字节流),通常是以文件的形式存在于本地文件系统或Web服务器上。

既然模块种包含类型的Meta信息,类型检查系统就可以联合静态和动态技术。当IL运行的时候,执行环境能得知
所有变量参数的类型Meta信息,自然就能执行运行时刻的类型检查——这被称之为 reflection(它的含义为解释自描述类型,类型的影子)。

== 程序集(Assembly) ==
程序集(Assembly)本身就是一个模块,程序集(Assembly)和模块(Module)间的区别,在于多了一个维护清单 manifest 【描述引用了哪些程序集,包含了那些模块文件,导出了哪些类型(其它模块中的),以及对自身的描述】。

多个模块文件可以被链接成一个程序集(assembly)。在程序集上多了一个清单(manifest),用来描述该程序集以及模块的列表,一个主入口,导出的类型定义列表(私有模块中公开的类型)。这份清单被放在一个模块上,
在该模块上的公开的类型不会出现在导出类型定义列表上!

程序集是CLI发布管理(deployment managed)的单位。程序集是可重用的软件组件。程序集甚至能动态绑定调用代码。
  * 程序集是独立的软件组件子集,无须重新编译。
  * 程序集是定制软件
  * 程序集能被独立发布
  * 程序集导出的API能和其它组件完美的交互。

程序集在文件系统中是用PE(portable executable)格式存放。引用的程序集是按需加载的,换句话说,只有当调用到该程序集的函数或类型之后,该程序集才会被加载:
  程序集加载器(assembly loader)将调用 CLI 下载器(downloader)加载该程序集
    CLI 下载器 根据搜索顺序从应用程序目录,子目录,本地文件Cache目录,或网络URL中装载。

== AppDomain和地址空间 ==

一个程序集将被加载到一个Application Domain(AppDomain)中执行。 外部引用的其它程序集将在同样同一AppDomain下运行。
换句话说,AppDomain 将程序集聚集在一起,实现最终功能。
每一个AppDomain定义了一个由CLI执行引擎管理的地址空间。所有的地址引用将确保实在同一个AppDomain中。
CLI地址空间是有层次的:AppDomain 能被加载入一个CLI地址空间。
CLI地址空间可以被概略的认为是OS中的进程地址空间(至少在Rotor CLI中是这样)。每一个地址空间都有明确的地址边界。

每一个CLI地址空间可以包含多个AppDomain: 其中一个AppDomain就是系统程序集,另一个AppDomain包含与其他与AppDomain共享的程序集。
只有CLI管理器(the supervision of the CLI)才能跨越AppDomain的地址空间访问进行交互。AppDomain之间的交互通讯是通过远程(Remoting)类型检查机制
完成。同样的机制被用于跨越地址空间,如接口和OS IPC.

模块,程序集,AppDomain和地址空间(address space)的关系是,模块是编译器建立的最小的单元文件,由一个或n个模块组成程序集,程序集是进行分发的
最小单元文件,程序集能组合在一个AppDomain下执行。多个AppDomain能在单个地址空间下执行。

【问】address space 是怎么构造的?最多能容纳几个AppDomain(进程空间能动态扩展)?什么时候需要新建另外一个address space?
【答】搞懂一些,基本上 一个CLR Host进程就是一个address space,然后建立多个 AppDomain,至于进程空间是否能动态扩展还要在看(也许代码是放在堆里)。AppDomain 使用来隔离程序集的。比如: ASP.Net 或者  Microsoft SQL Server。
每一个AppDomain之间不能彼此影响,是完全独立的,这样保证了AppDomain的安全!必须做到一个AppDomain中出了错误,而不影响到另一个AppDomain.