俺的垃圾箱

架构分析 解释编译原理
posts - 36, comments - 233, trackbacks - 12, articles - 1
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

CLI 架构(Architecture) (2)

Posted on 2006-12-16 12:34 Riceball LEE 阅读(1857) 评论(6)  编辑 收藏 网摘 所属分类: CLR框架
== Virtual Execution System(VES) ==
VES是CLI DVM(分布式虚拟机)的心脏。Execution Engine (EE) 则是其核心了,代码在 MSCOREE (Microsoft Common Object Runtime EE) 中。
引用的程序集可以存在于任何地方,比如一台web服务器上,当EE被请求装载(Downloading)该程序集的时候,将会做以下的事情:
  检查调用者认证
  检查程序集是否有效
  一切搞定则将程序集装载到AppDomain
一旦程序集被加载到AppDomain,那么在AppDomain中的其它代码将能访问该程序集中的公开成员和字段,当然上在EE的监督下。
不过这时候,程序集中的类并没有被绑定到代码,只有当对该类的调用真的发生的时候,EE才会去查找在程序集中的目标类并将其
装载入AppDomain,然后校验访问许可,从该类的Meta信息中提取目标类的细节说明,然后Build an appropriate call table data structure.
当第一次引用类成员的时候,它的形式还是中间代码,CLI 总是使用JIT编译器(JITter)将中间代码翻译成本地机器码,然后当下次再次
引用的时候就会直接执行编译好的本地机器码。EE还包括了垃圾收集器和结构化异常处理器。

EE 执行流程,通过一个最简单的主程序说明:
static void Main() {
  Console.WriteLine("Hello");
}

在 Main 方法被执行前,CLR将检测所有被Main中的代码引用的类型,CLR将会为所有的引用类型分配一块内部数据,内部数据中包含了定义的类型中的每一个方法的入口。
每一个方法入口包含了该方法的执行地址,当该内部数据初始化的时候,CLR将每一个入口指向一个内部函数:JITCompiler.
ok, 第一次调用WriteLine方法的时候,实际上是 JITCompiler 函数被调用,JITCompiler 函数知道被调用方法是哪一个(根据传入的Self对象指针),然后 JITCompiler
函数查找程序集的MetaData取得该方法的IL,然后校验并编译IL成为本地CPU指令,编译的本地CPU指令被放在动态分配的内存块中,接着 JITCompiler 函数将WriteLine的
内部数据的方法入口替换成编译好的本地CPU指令执行入口。最后, JITCompiler 函数跳转到该入口处执行。

JITCompiler 存放的本地CPU指令随着应用的终止而自动被释放(除非使用 NGen.exe),当再次运行的时候,那么JITCompiler将再次编译,如果你同时运行两个应用实例
那么JITCompiler也将会再编译一次。嘿嘿,如果你的应用程序大部分的方法代码都只被调用一次,那么这速度性能将变得很糟糕,尤其是打开了JITCompiler优化的情况下
更慢,当然大多数应用程序决不可能写出的方法代码只被调用一次的,这只能视作极端情况。

另外,我很想知道的,IL(MetaData)加载到内存是什么时候?实际上IL只有当JITCompiler编译的时候才需要,如果一直都放在内存那就太浪费了。


== Remoting 机制 ==
Remoting 机制作为在AppDomain之间沟通的桥梁,当你引用你一个AppDomain的对象或成员的时候,Remoting就要负责处理了。Remoting 也被用于
在地址空间之间沟通。Remoting 是在 MarshalByRefObject 类中实现的。
它的实现机制如下:
服务器端:远程访问的对象是 MarshalByRefObject 子类的实例,通过使用该基类,CLI就有能力为远程对象建立Real Proxy server Stub,
这个代理服务器将被注册到全局名称空间,然后准备好运行时间链接(当客户对象调用远程对象的时候用以支持RMI)。
通道(Channel)对象被MarshalByRefObject子类实例化并注册。

客户端:通道在使用前必须先注册。当客户引用远程对象,位于客户端的透明代理(Transparent Proxy)被建立。将调用数据序列化(serializes)后通过代练被传送到服务器。

看样子,就算是同一进程下的不同AppDomain之间的调用通讯,也是慢得不得了啊。这个不外乎就是以前的AO实现的远程调用,只不过被包裹在内核
普通开发者看不到,这个暂缓研究。



Feedback

#1楼   回复  引用  查看    

2006-12-16 16:58 by neoragex2002      
翻译Inside the Rotor的?

#2楼[楼主]   回复  引用  查看    

2006-12-16 17:32 by Riceball LEE      
@neoragex2002
呵呵,俺看的不止这一本,做的笔记。

#3楼   回复  引用    

2006-12-17 12:23 by idior[匿名][未注册用户]
虽然CLI CLR的内容很有价值,但是像你这样流水账的写法,效果就大打折扣了,不如等你有了深刻体会,自己重新组织后,再放到首页吧。

#4楼[楼主]   回复  引用  查看    

2006-12-17 16:04 by Riceball LEE      
@idior[匿名]

欢迎您提供些高质量的CLI分析给大家,或者指出我的错误,都欢迎!
但是,说空话,就没有必要了。你以为我要写书啊,懂不懂什么叫笔记。

#5楼   回复  引用  查看    

2006-12-17 16:49 by dudu      
@Riceball LEE
笔记并不适合发表在首页,除非笔记中有很多自己的思考。

#6楼[楼主]   回复  引用  查看    

2006-12-17 21:08 by Riceball LEE      
@dudu

ok, 受教了,俺只不过想吸引更多的人来共同解剖CLI.



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 594117




相关文章:

相关链接: