zoukankan      html  css  js  c++  java
  • 读书笔记—CLR via C#章节1-2

    这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可以加深自己理解的深度,当然同时也和技术社区的朋友们共享。

    程序集

    • 描述:一个或多个类型定义文件及资源文件的集合
    • 特征:可重用、可保护、可版本控制的单元
    • 生成:可通过C#编译器(或其他编译器)或AL.exe生成
    • 组成:
      • 托管模块(module)
        • PE头,PE32或PE32+,面向CPU架构的信息
        • CLR头,面向CLR的信息,版本、入口、元数据等
        • 元数据,源代码类型成员定义和引用的类型成员定义
        • IL代码,编译器生成的托管代码,面向对象的机器语言
      • 资源文件
      • 程序集清单

    CPU架构

    针对x86、x64和IA64三种平台有三个版本的CLR,信息包含在PE头中

    • 跨CPU架构:使用anycpu,兼容所有CPU架构平台
    • 指定CPU架构:与非托管交互时,考虑到非托管接口的平台特定性,才使用特定CPU架构
    /开关 托管模块 x86 windows x64 windows IA64 windows
    anycpu PE32/不指定 32位 64位 64位
    x86 PE32/x86 32位 Wow64运行 Wow64运行
    x64 PE32+/x64 不运行 64位 不运行
    Itanium PE32+/Itanium 不运行 不运行 64位

    元数据

    • 编译时支持,已包含和引用的类型/成员有关的全部信息
    • 智能感知(Intelligence),成员(方法、属性、事件和字段)及方法参数
    • 验证类型安全
    • 反射和序列化(对象激活与对象重建)
    • 垃圾回收,垃圾收集器能判断对象类型以及对象字段的引用信息

    执行流程

    1. 判断是否存在已编译的本地代码,如果存在直接执行(3),否则开启JIT编译器
    2. 启动JIT编译(MSCorEE.dll)
      1. 在元数据中查找调用信息(方法等)
      2. 获取该调用信息的IL
      3. 分配内存块DynamicMemory
      4. 编译IL为本地CPU指令,并存储到DynamicMemory
      5. 修改Type表调用指针指向DynamicMemory
      6. 跳转到DynamicMemory中的本地代码
    3. 执行本地代码(CPU指令)

    image

    编译过程

    有两个C#编译器开关会影响代码的优化:/optimize和/debug,请看下表:

    编译器开关设置 C# IL代码质量 JIT本地代码质量
    /optimize- /debug(默认) 未优化 有优化
    /optimize- /debug(+/full/pdbonly 未优化 未优化
    /optimize+/debug(-/+/full/pdbonly 有优化 有优化

    优缺点比较:

    • 未优化(/optimize-),未优化IL代码,包含许多NOP(no-operation)指令,还包含分支指令,优点是即使调试
    • 优化的IL代码,编译器删除多余的NOP和分支指令,代码更小,但却难以单步调试

    编译器默认调试配置

      • Debug: /optimize- /debug:full
      • Release: /optimize+ /debug:pdbonly

    性能神器 – JIT

    • 将IL编译为本地代码时,对环境的理解比其他编译器更加深刻
    • 生成面向特定CPU的指令,有效利用不同平台的资源提高效率
    • 优化代码,使IL更加轻量,并且更容易理解

    鸡肋?NGen.exe

    优点:

    • 预编译保存在磁盘上,加快启动速度
    • 减小工作集,进程之间共享代码(通过内存映射)

    缺点:

    • 对代码无优化
    • 较差的执行时性能(无特定CPU指令优化,运行时字段无法直接访问)

    部署

      私有部署 全局部署
    弱命名程序集 支持 不支持
    强命名程序集 支持 支持

    私有程序集部署特征:引用程序集存放在基目录或者基目录的子目录

    探测范围:基路径 - 配置路径 - 相同名称子路径 - 语言文化子目录

    私有程序集目录配置:

    <configuration>
      <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
          <probing privatePath="AuxFiles1,AuxFiles2" />
        </assemblyBinding>
      </runtime>
    </configuration>

    其他(Other Tips)

    SDK工具

    • IL编译及反编译 – ILAsm.exe/ILDasm.exe
    • CLRVer.exe 查看CLR版本
    • DumpBin.exe和CorFlags.exe,查看托管模块所嵌入的信息
    • 安全检查工具:PEVerify.exe

    IL是中间语言,支持混合编程,C#只是利用CLR的一个子集,IL则是完全面向CLR的

    CLR启动入口(MSCorEE.dll)(3种CPU架构3个版本,负责加载程序集)

    WoW64能模拟x86指令集

    CLS语言规范,规范混合语言之间的互操作 [assembly: CLSCompliant(true)]

    语言互操作

    • 托管代码调用dll中的非托管函数(PInvoke平台调用)
    • 托管代码使用现有的COM组件
    • 非托管代码使用托管类型
    • 开源实现:http://CLRInterop.CodePlex.com

    响应文件,rsp文件,包含一些编译开关参数,系统全局响应文件自动引用默认程序集

    程序集搜索目录及顺序

    1. 工作目录
    2. CSC.exe本身目录
    3. /lib 指定的目录
    4. LIB环境变量指定的目录

    多文件程序集,编译器将module合并,addmodule开关,也可以使用AL.exe,用处:

    1. 单独文件存储类型,允许增量更新,分批打包/部署
    2. 嵌入资源
    3. 不同的语言进行实现,然后再合并

    程序集文化

    • 语言文化包括特定文化或者文化中性
    • 附属程序集,使用System.Resources.ResourceManager访问附属程序集的资源
    • 设置方式   1:AL.exe /culture    2:[assembly:AssemblyCulture(“de-CH”)]
  • 相关阅读:
    leetcode 78. 子集 JAVA
    leetcode 91. 解码方法 JAVA
    leetcode 75. 颜色分类 JAVA
    leetcode 74 搜索二维矩阵 java
    leetcode 84. 柱状图中最大的矩形 JAVA
    last occurance
    first occurance
    classical binary search
    LC.234.Palindrome Linked List
    LC.142. Linked List Cycle II
  • 原文地址:https://www.cnblogs.com/fecktty2013/p/readingnotes-clr-12.html
Copyright © 2011-2022 走看看