托管和非托管代码,内存和大小有什么不同?

在查看并听取了很多关于托管代码和非托管代码的信息之后,了解到唯一的区别是托管的是关于CLR的,而未托管的则不在CLR之中,这让我非常好奇,要详细了解它。 这是什么,托管和非托管代码,内存和大小?

在C#代码中,我如何用C#编写的代码处于非托管状态,以及内存大小如何变得不受管理。 一个例子和一点洞察力将会有所帮助。


简短的回答:

  • 托管代码是您编写和编译为.NET CIL的.NET代码(VB.NET,C#等)。
  • 非托管代码是不在.NET下的代码,用于编译指导机器代码。
  • 长答案:

    什么是托管代码?

    托管代码是Visual Basic .NET和C#编译器创建的。 它编译为中间语言(IL),而不是可以直接在您的计算机上运行的机器代码。 CIL保存在一个名为程序集的文件中,以及描述您创建的代码的类,方法和属性(如安全要求)的元数据。 这个程序集是.NET世界中的一站式购物单元。 将其复制到另一台服务器以在该处部署该程序集 - 并且通常复制是部署中所需的唯一步骤。

    托管代码在公共语言运行时中运行。 运行时为运行代码提供各种服务。 在通常的事件过程中,它首先加载并验证程序集以确保CIL没问题。 然后,随着方法被调用,运行时会安排将它们编译为适合运行程序集的机器的机器代码,并在下次调用方法时缓存该机器代码以供使用。 (这叫做Just In Time,或JIT编译,或者经常只是Jitting。)

    在程序集运行时,运行时将继续提供安全性,内存管理,线程等服务。 该应用程序由运行时管理。

    Visual Basic .NET和C#只能生成托管代码。 如果您正在使用这些应用程序,则您正在创建托管代码。 如果您喜欢,Visual C ++ .NET可以生成托管代码:创建项目时,选择名称以.Managed开头的其中一个应用程序类型,例如.Managed C ++应用程序..

    什么是非托管代码?

    非托管代码是您在Visual Studio .NET 2002发布之前所使用的代码。 Visual Basic 6,Visual C ++ 6,甚至可能还有15年历史的C编译器在您的硬盘驱动器上运行,都会生成非托管代码。 它直接编译为机器代码,并在编译它的机器上运行 - 只要它们具有相同的芯片或几乎相同,就可以在其他机器上编译。 它没有从不可见的运行时间获得安全或内存管理等服务; 它从操作系统中获得了它们。 重要的是,它通过询问它们,明确地从操作系统中获得它们,通常通过调用Windows SDK中提供的API。 最近的非托管应用程序通过COM调用获得了操作系统服务。

    与Visual Studio中的其他Microsoft语言不同,Visual C ++可以创建非托管应用程序。 在创建项目并选择名称以MFC,ATL或Win32开头的应用程序类型时,您正在创建一个非托管应用程序。

    这可能会导致一些混淆:当您创建.Managed C ++应用程序时,构建产品是带有.exe扩展名的CIL程序集。 当您创建MFC应用程序时,构建产品是本机代码的Windows可执行文件,并带有.exe扩展名。 这两个文件的内部布局完全不同。 您可以使用中间语言反汇编程序ildasm查看程序集内部并查看元数据和CIL。 尝试将ildasm指向非托管exe文件,您会被告知它没有有效的CLR(公共语言运行时)标头,并且无法反汇编 - 相同的扩展名,完全不同的文件。

    原生代码呢?

    短语本地代码在两个上下文中使用。 许多人将它用作非托管代码的代名词:使用旧工具构建的代码,或者故意在Visual C ++中选择的代码,该代码不在运行时运行,而是在本机上运行。 这可能是一个完整的应用程序,或者它可能是一个COM组件或DLL,它使用COM Interop或PInvoke从托管代码中调用,这两个功能强大的工具可确保您在转移到新世界时可以使用旧代码。 我更愿意说.unmanaged代码。 为了这个意思,因为它强调代码没有得到运行时的服务。 例如,托管代码中的代码访问安全性可防止从其他服务器加载的代码执行某些破坏性操作。 如果您的应用程序调用从其他服务器加载的非托管代码,则不会得到该保护。

    短语本地代码的另一个用途是描述JIT编译器的输出,即运行时实际运行的机器代码。 它的管理,但它不是CIL,它是机器代码。 因此,不要只假定native = unmanaged。

    (资源)


    这可能是一个非常长的答案,讨论了C编译器生成的机器代码与JIT编译器从托管程序生成的机器代码之间的许多细微差别。 足够长的时间才能真正需要一本书,但这些书已经写好了。 例如Jeffrey Richter的任何内容。

    我会保持简短和快速,因为所有这些微妙的差异归结为一条规则:

    托管代码是从垃圾回收堆中分配内存的代码。


    通常托管代码比等效的良好编写的非托管(本地)代码具有更高的运行时内存占用量。

    链接地址: http://www.djcxy.com/p/54501.html

    上一篇: What is the difference in managed and unmanaged code, memory and size?

    下一篇: How do you prevent IDisposable from spreading to all your classes?