启动.net应用程序时会发生什么?

时间:2011-07-07 04:50:52

标签: c# .net clr

我一直在使用.net开发应用程序已经有一段时间了。但是,我仍然没有 确定CLR如何知道.net应用程序已经启动。是否每个应用程序都有一个CLR实例?我不认为这可能是这种情况,因为只有一个GC管理所有.net应用程序的所有内存。 CLR是否在后台运行?我很困惑。

2 个答案:

答案 0 :(得分:43)

嗯,让我来看看这个。

  1. 有人用C#或.NET“中间语言”或其他托管语言构建.NET应用程序。

  2. 该语言的编译器csc.exe(C#)或ilasm.exe(字节码汇编程序)或其中任何一个生成PE可执行文件。 PE可执行文件具有编译器或汇编程序填充的特定结构。这包括:

    • 一个入口点,
    • 它使用的动态库列表(IMPORT表)。其中一个库是mscoree.dll
    • 许多元数据,包括目标.NET运行时版本
  3. 单击可执行文件,从命令行运行或从Win32 API执行时,Windows loader implementation(在NTDLL.dll中)接管

  4. 加载程序代码负责将可执行文件存入内存,根据需要加载动态链接库,将链接库映射到可执行代码可以访问它们的位置,并使用实际地址更新导入地址表。映射库。

  5. 一旦准备就绪,加载程序就会跳转到入口点(通过我假设的是一些恶作剧从内核空间切换到用户空间,或者转换到保护模式,因为应用程序在它自己的受保护的32或64中运行位存储空间)。入口点是mscoree.dll - .NET公共对象运行时执行引擎,它刚刚映射到进程内存中。 我已经看到这个DLL被称为.NET启动垫片,它允许在一台机器上存在多个.NET安装。如果您在自己的常规应用程序中嵌入.NET语言,则Mscoree.dll是您将使用的库。

  6. Mscoree.dll查看从PE可执行文件加载的元数据,特别是CLR标头和目标.NET运行时版本。从那以后它可以CorBindToRuntimeEx 2到正确的CLR版本。

  7. CorBindToRuntimeEx加载正确的.NET运行时实现(并返回一个指向COM接口的指针,允许您调用该.NET运行时。此代码从%WINDIR%\ Microsoft.NET \ Framework中的dll加载\ v #####。

  8. 我不确定此时是谁,但可能是mscoree shim使用.NET ICLRRuntimeHost接口指针来调用方法来初始化.NET运行时,垃圾收集器,IL解释器,JIT和IHostControl接口(允许.NET解释器与托管进程对话),并最终告诉Interpreter开始执行已编译应用程序的IL代码。

  9. (我学到了很多东西 - 链接背后有很多信息,我当然没有完全了解所有这些!)

    http://msdn.microsoft.com/en-us/library/xh0859k0.aspx

    http://my.safaribooksonline.com/book/programming/microsoft-dotnet/0735619883/a-tour-of-the-clr-hosting-api/ch02lev1sec3

    http://msdn.microsoft.com/en-us/magazine/bb985994.aspx

答案 1 :(得分:5)

Windows可执行文件是Portable Executables,这种格式为Windows提供加载和运行程序所需的信息。当Windows遇到.NET程序时,它会加载CLR的一个实例,并将程序的执行交给新的CLR实例。每个运行的.NET程序都托管在它自己的CLR实例中。

CLR进程加载IL程序并将其编译为Native Code(JIT),然后执行代码,负责该程序的内存管理和垃圾收集。