托pipe和非托pipe代码,内存和大小有什么区别?

关于托pipe代码和非托pipe代码,在看到和收听很多内容之后,知道唯一的区别就是托pipe的是关于CLR,而非托pipe的是CLR之外的,这让我真的很好奇。 这是什么,pipe理和非托pipe的代码,内存和大小?

如何在C#中编写的代码不受托pipe,而这是C#代码,以及如何将大小内存变得不受pipe理。 一个例子和一个小洞察将是有帮助的。

简短的回答:

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

很长的回答:

什么是托pipe代码?

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

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

运行时,运行时会继续提供安全性,内存pipe理,线程等服务。 应用程序由运行时pipe理。

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

什么是非托pipe代码?

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

与Visual Studio中的其他Microsoft语言不同,Visual C ++可以创build非托pipe应用程序。 当您创build一个项目并select名称以MFC,ATL或Win32开头的应用程序types时,您正在创build一个非托pipe应用程序。

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

原生代码呢?

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

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

( 来源 )

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

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

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

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

托pipe代码在应用程序域中运行,非托pipe代码在操作系统的运行下运行。