zoukankan      html  css  js  c++  java
  • CLR笔记:1.CLR的执行模型

    术语:    CLR :Common Language Runtime 公共语言运行期,有多种不同编程语言使用的运行库
                    托管模块:Managed Module,一个标准的MS Window可移植执行体文件(32位PE32或64位PE32+)
                    IL:Intermediate Language 中间语言,又叫托管代码(由CLR管理它的执行)
                    元数据:metadata,一系列特殊的数据表
                    程序集:Assembly,抽象的
                    JIT:just-in-time 即时编译,将IL编译成本地CPU指令(本地代码)
                    FCL:Framework Class Library,Framework 类库
                    CTS:Common Type System,通用类型系统,描述了类型的定义及其行为方式
                    CLI:Common Language Infrastructure,公共语言基础结构,这是MS提交给ECMA的一个标准,由CTS和其他Framwork组件构成
                    CLS:Common Language Specfication,公共语言规范,详细规定了一个最小特性集

    1.1    将源代码编译成托管模块
    CLR编译过程: C#源码文件——C#编译器编译——托管模块(IL和元数据)

    托管模块的各个部分:
           1.PE32或PE32+头 
                标志了文件类型,GUI/CUI/DLL,文件生成时间,在32位还是64位上运行
           2.CLR头
                CLR版本,入口方法,模块元数据,资源,强名称
           3.元数据
                3种类型的表
           4.IL代码

    元数据包括:
           1.描述了模块中定义的内容,比如类及其成员
           2.指出了托管模块引用的内容,比如导入的类及其成员
           3.清单manifest,描述了构成Assembly的文件,由Assembly中的文件实现的公共导出类型,与Assembly相关联的资源/数据文件
    元数据总是嵌入到与代码相同的EXE/DLL中,始终与IL保持同步。

    元数据用途:
           1.消除了对头/库文件的依赖,直接从托管模块中读取
           2.智能感知,从元数据中解析
           3.代码验证,使用元数据确保代码只执行安全操作
           4.正反序列化
           5.垃圾收集器跟踪对象的生存期以及对象的类型

    1.2    将托管模块合并成程序集
    程序集:一个或多个托管模块/资源文件的逻辑分组,是最小的重用,安全性以及版本控制单元。
            既可以生成单文件程序集,也可以生成多文件程序集,这由编译器工具决定。
            CLR是和程序集一起工作的,而不是和托管模块

    1.3    加载CLR
        CLRVer命令,查看机器上所有CLR版本
        csc的 /plattform开关,决定生成什么样的程序集:AnyCPU,x86,x64,Itanium

    1.4    执行Assembly代码
        ILAsm命令,将IL编译成Assembly;ILDasm将Assembly编译成IL。
        高级语言(C#)只是CLR的一个子集,IL则允许访问CLR的所有功能。
        JITCompiler函数,又名JIT编译器(JITter)
            在方法首次执行时,CLR检测出Main的代码引用的所有类型,于是CLR分配一个内部数据结构,用于管理对引用类型的访问。
            在这个内部结构中,每个方法都有一条对应的纪录以及地址。
            对此结构进行初始化时,CLR将每条纪录都设置为CLR内部包含的一个未文档化的函数,即 JITCompiler函数。
            JITCompiler函数被调用时,找到相应方法的IL,编译成本地CPU指令,并保存到一个动态内存块中,将该内存地址存入内部结构中,最后JITCompiler函数会跳转到内存块中的代码,执行。
            第二次执行该方法时,不需要再编译,直接执行内存块中的代码。

            JIT将本地代码保存在动态内存中,一旦程序终止,本地代码会被丢弃。

            csc命令有2个开关会影响代码的优化:/optimize ,/debug

    开关设置 IL代码质量 JIT本地代码质量
    /optimize- ,/debug- 未优化 优化 默认设置
    /optimize- ,/debug(+/full/pdbonly) 未优化 未优化 VS2005 Degug状态
    /optimize+ ,/debug(-/full/pdbonly) 优化 优化 VS2005 Release状态

    生成未优化的IL时,会在IL中生成NOP指令用于调试,设置断点。

    IL是基于堆栈的。所有指令都是:将操作数压栈,结果则从栈中弹出
    IL有安全验证机制,保证每一行IL代码是正确的,不会非法访问内存,每个托管EXE都在独自的AppDomain中运行。

    不安全代码:允许C#直接操作内存字节,在COM互操作时使用,csc以/unsafe开关标记包含不安全代码,其中所有方法都使用unsafe关键字。
    PEVerify命令检查程序集所有方法,指出其中的不安全代码方法。

    1.5    本地代码生成器 NGEN.exe
    NGEN.exe将IL预先编译到硬盘文件中,可以加快程序的启动速度,减小程序的工作集(所有加载该程序集的AppDomain不再copy其副本,因为该程序集已经与编译到文件中,是代码共享的)。
    缺点是:
        不能保护IL外泄
        生成的文件可能失去同步
        因为在文件中要计算首选基地址,而NGEN是静态计算好的,所以要修改基地址,速度会慢下来
        较差的执行性能,NGEN生成的代码没有JIT好。
    如果不能使用NGEN生成的文件,会自动加载JITCompiler。

    1.7    CTS
        CTS的一些规定:
            1.一个类型可以包含0个或多个成员
            2.类型可视化以及类型成员的访问规则
            3.定义了继承,虚方法,对象生成期的管理规则
            4.所有类型最终都从预定义的System.Object继承

    1.8    CLS
        如果在C#中定义的类型及其方法,可以在VB中使用,那么,就不能在C#中定义CLS外的任何public/protected特性,privated的类型及其成员不受限制。
        C#可以有仅大小写不同的两个方法——不符合CLS,所以不能是public的。
        
        使用[assembly:CLSComplant(true)]标志程序集,告诉编译器检查该程序集的CLS相容性。书上写得不明白,我这里做了一个测试:

    using System;

    [assembly: CLSCompliant(
    true)]

    namespace ClassLibrary2
    {
        
    public class Class1
        
    {

            
    public void A()
            
    {

            }


            
    public void a()
            
    {

            }

        }

    }

    注意,[assembly:CLSComplant(true)]要写在namespace外。
    我定义了两个不同方法A和a,编译器会有警告,说这样的语法不兼容CLS;如果去掉[assembly:CLSComplant(true)]声明,那么不会有这个警告;如果将a方法改为private,则不会有警告。
    中途我使用了ILDasm观察这个dll,发现两个方法A和a都存在于IL中,说明IL的语法范围也大于CLS。
    在VB中,我添加了对此dll的引用:

    Imports ClassLibrary2

    Module Module1

        
    Public Class T
            
    Public Function A() As Integer

                
    Dim c1 As Class1 = New Class1()


            
    End Function

        
    End Class


    End Module

    发现,在c1.后面不会有A或a方法的智能感知,说明VB不能识别不符合CLS的语法。如果修改了dll中的a方法为private或者删除a方法,则在VB中可以智能感知到A方法。
    可以得出结论,不符合CLS的语法,在另一种语言中是看不到的。
        
    1.9 COM互操作
        3种互操作情形:
            1.托管代码可以调用DLL中包含的非托管函数,如Kernal32.dll,User32.dll
            2.托管代码可以使用现成的COM组件
            3.非托管代码可以使用托管类型(C#写的ActiveX控件或shell扩展)

  • 相关阅读:
    MongoDB 4.0.10 CRUD操作(增删改查)
    MongoDB 4.0.10 聚合
    MongoDB 4.0.10 索引
    MongoDB 4.0.10 导出、导入,备份、恢复
    MongoDB 4.0.10 监控
    列及注释
    SecureCRT的shell中文乱码
    oracle 判断是否是日期
    查询oracle服务器的版本
    Oracle中connect by 的执行结果记载
  • 原文地址:https://www.cnblogs.com/Jax/p/893591.html
Copyright © 2011-2022 走看看