CLR简介(三)

“托管代码”概念

能够执行额外记录一般在“几乎任何时刻”报告其正在使用的有效GC引用的代码,就称做 托管代码 (因为其被CLR“管理”)。不能实现这个目标的代码叫 非托管代码。因此在CLR之前存在的代码都是非托管代码,特别来说,所有操作系统的代码都是非托管的。

堆栈展开的问题

由于托管代码需要用到操作系统的服务,所有有时托管代码需要调用非托管代码。相应的,托管代码最初是操作系统启动的,因此有时非托管代码也会调用托管代码。因此,当你在任意位置中断托管程序,堆栈上混合了由托管代码和非托管代码创建的帧。

非托管代码的堆栈帧对其上运行的程序 没有 要求。即一般不要求 展开 (非托管堆栈帧)来找到它的调用者。这意味着当程序在非托管函数中断时,一般[1] 是没有办法找到它的调用函数的。只能在调试器里才能做到,这是因为在符号(PDB)文件里保存了额外信息。但这些信息不保证一直存在(这就是为什么在调试器里无法获取准确堆栈信息的原因)。这在托管代码里是很大的问题,因为在无法展开的堆栈里可能包含托管代码帧(它包含了需要收集的GC引用)。

托管代码有一些额外需求:不仅是在运行过程中需要跟踪所有的GC引用,而且还需要能展开它的调用函数。另外,无论何时从托管代码到非托管代码(或发过来)的过渡,托管代码都需要做一些额外的记录来避免非托管代码无法展开堆栈带来的影响。实际上,托管代码在堆栈里将托管代码帧链接起来了。因此,即使在无法利用额外信息展开非托管代码堆栈帧的情况下,还是能在堆栈上找到托管代码块并枚举托管代码帧。

[1] 最近的平台ABI(应用程序二进制接口 application binary interfaces)定义了编码这些信息的约定,但其不是一个所有代码都必须遵循的严格规范。

托管代码的“世界”

结果就是进出托管代码的每次过渡都要做特殊的记录。托管代码只能在CLR理解的“世界”。这两个世界是非常不同的(在任何时刻,代码要么在 托管世界,要么在 非托管世界)。而且,因为在CLR格式里定义了托管代码的执行(即 [通用中间语言]cil-spec),并由CLR在原生硬件上解释执行,CLR对运行情况有 非常多 的控制。例如,CRL可以更改从一个对象里获取字段的值或调用一个函数的意思。实际上,CLR在创建MarshalByReference对象时就是这么做的。它们看起来是普通的本地对象,但实际上存在于另外一台机器。简单来说,CLR的托管世界里有很多 运行时钩子 来支持后续章节要介绍的强大功能。

另外,托管代码还有一个很重要但不是很明显的衍生物。在非托管代码里,GC指针是不被允许的(因为其不可被跟踪),在托管和非托管之间的切换有一个记录的成本。这意味着虽然你 可以 在托管代码里调用任意的非托管方法,但过程通常不是很方便。非托管代码无法使用GC对象作为其参数或者返回值,也就是说这些非托管方法创建和使用的任何“对象”或“对象引用”都需要显式释放。这实在是个悲剧。因为这些API无法享受到诸如异常或继承这样的CLR的功能的益处,这将会导致与托管代码交互时“不匹配”的用户体验。

其结果就是大部分非托管接口在暴露给托管代码开发者时是 封装的。举个例子,当访问文件时,一般不使用操作系统提供的Win32 CreateFile 函数,而是用封装了其的System.IO.File托管代码类。实际上直接使用非托管API的地方非常少。

虽然这种封装在一些地方看起来“差劲”(更多的代码不见得做的更多),实际上它还是增加了一些价值的。请记住直接暴露非托管接口总是可能的;但我们选择封装这些功能,为什么?因为整个运行时设计的首要目标是使编程更简单,而且一般来说非托管代码不是足够简单。通常来说,非托管接口一开始就不是为了使用简单而设计的,而是为完整性优化的。当你看到CreateFile或者CreateProcess函数的参数列表时,很难将其归类到简单里。幸运的是,这些接口进入托管世界“整了次容”,虽然过程很“没技术含量”(无非就是重命名,简化,重组其功能),但非常有用。为CLR编写的一个非常重要的文档就是 [Framework Design Guidelines][fx-design-guidelines]。这本800+页的文档详细描述了创建新的托管代码类库的最佳实践。

到这里,我们分析了托管代码和非托管代码里两个重要不同:

  1. 高科技:代码在两个不同的世界里运行,而CLR在程序运行时的各个方面进行良好的把控(甚至到单个指令级别),而且CLR可以检测什么时候进入或退出托管代码的运行。这点使很多有用的功能变得可能。
  2. 低技术含量:在托管和非托管代码之间有切换成本,而且非托管代码无法使用GC对象这点事实鼓励用facade模式封装非托管代码。即通过遵循一系列的命名和设计指南来达到一定程度的一致性和可发现性来“整容”并简化(操作系统)接口。

上面两个特性对于托管代码的成功都非常重要。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容

  • 托管 vs. 原生线程 托管代码在“托管线程”上执行,(托管线程)与操作系统提供的原生线程不同。原生线程是在物理机...
    懿民阅读 679评论 0 5
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,590评论 18 139
  • 《腾讯桌球:客户端总结》 本次分享总结,起源于腾讯桌球项目,但是不仅仅限于项目本身。虽然基于Unity3D,很多东...
    吴秦阅读 24,378评论 12 142
  • 1. [C#语言基础]请简述拆箱和装箱。 答: 装箱操作: 值类型隐式转换为object类型或由此值类型实现的任何...
    胤醚貔貅阅读 4,767评论 1 29
  • 阿发和阿花是兄妹,两个人除了白天各打一份工,晚上还经营着一间馄饨铺子。 铺子开在繁华的商业街上,五六平方,一般晚上...
    任真阅读 578评论 18 33