• .net知识和学习方法系列(十六)CLR-托管理程序和它的运行


    大家都知道,vs生成的是托管理程序(不管是VB.net还是C#),托管理程序是什么呢?托管这个词就能隐约得告诉我们,这个程序运行时不那么“单纯”,其实,托管理程序是不可以直接在CPU上运行的,至于为什么,我们先看一下托管程序的组成部分。

    一般托管理程序分为

    PE文件头:包含文件的类型,还有生成文件的时间

    CLR头:包含CLR版本,入口方法的元数据标记

    元数据:定义的类型和成员,引用的类型和成员

    IL(中间语言):编译源代码时生成的代码

     

    现在来看一下托管理代码的运行,有这样一个简单的方法

    using System;

    class Democlass

    {

        static void Main()

        {

            Console.WriteLine("谢谢!");

            Console.WriteLine("阅读。");

    Console.WriteLine("再见!");

        }

    }

    IDE把把这个代码编译成exe后,我们运行起这个exe(当然是在装有.net Framework的计算机上),首先CLR会扫描所有这个Main方法中的类型,然后会创建一个用于管理这些类型的数据结构,虽然本例中只有一种类型Console,并且还是一个静态类。在这个数据结构中,存放着很到记录,每个记录与Console的一个方法对应着,每个记录中,包含着一个指向方法实现的内存地址。

    当这个数据结构初始化时,CLR就将数据结构中的每条记录指向一个在CLR中已定义好的方法CallMethod(我假设的名子),这个方法能根据记录找到方法实现,当执行Console.WriteLine(“谢谢!”)时,会在数据结构中找到对应的记录,这个记录会调起CallMethod方法,CallMethod这个方法要实现 步骤如下:

    A.        调用元数据中的WriteLine方法(因为记录与CallMethod关联,记录指向方法的实现地址,所以CallMethod能调用WriteLine方法)

    B.        从元数据中得到这个方法的IL

    C.        申请一块内存空间

    D.        把这个方法编译成CPU指令,放到申请的内存空间中

    E.         然后这个方法返回到这个数据结构中的WriteLine方法对应的那条记录,用申请的内存地址替换掉这个记录包含指向方法实现的内存地址(这里就是用CPU指令所在的内存地址替换掉了实现方法的内存地址)

    F.         返回Main方法的Console.WriteLine(“阅读”)

     

    CLR执行Main方法的Console.WriteLine(“阅读”)时,因为记录中的内存地址已变成了CPU指令所在的内存地址,所以这次,CallMethod方法就不用被重新调用,这就说明,一旦该方法第一次被调用过,以后的调用就相对的节省资源了。直到该程序中止退出。

    如果该程序在一台计算机上启动了两个,它们的这个该方法的CPU指令是不会被共用的,因为他们不在一个Application Domain,不能跨域访问。
  • 相关阅读:
    编译问题汇总
    IAP测试购买失败,Error Domain=SKErrorDomain Code=0 "无法连接到 iTunes Store"
    关于H5移动端调试的那些事
    关于JS中this指向的说明
    关于UIControl响应事件说明
    绝对独创---关于直播(推流-拉流-服务器搭建)
    关于直播
    关于公司视频播放由mp4格式向m3u8格式转换的学习
    关于UIView中的endEditing:的使用
    关于UITableViewCell左滑显示多个功能的实现
  • 原文地址:https://www.cnblogs.com/axzxs2001/p/1290164.html
Copyright © 2020-2023  润新知