在看到和听取很多关于托管和非托管代码之后,并且知道唯一的区别是托管是关于CLR而未托管是在CLR之外,这让我非常好奇地了解它。它是什么,托管和非托管代码,内存和大小?
我在C#中编写的代码如何是非托管的,而这是C#代码,以及大小的内存如何变得不受管理。一个例子和一点点见解会有所帮助。
答案 0 :(得分:142)
简短回答:
答案很长:
托管代码是Visual Basic .NET和C#编译器创建的代码。它编译为中间语言(IL),而不是编译可以直接在您的计算机上运行的代码。 CIL保存在一个名为程序集的文件中,同时还包含描述您创建的代码的类,方法和属性(如安全性要求)的元数据。这个程序集是.NET世界中部署的一站式购物单元。您将其复制到另一台服务器以在那里部署程序集 - 通常复制是部署中唯一需要的步骤。
托管代码在公共语言运行时中运行。运行时为运行的代码提供各种服务。在通常的事件过程中,它首先加载并验证程序集以确保CIL正常。然后,就在调用方法时,运行时会安排将它们编译为适合运行程序集的机器的机器代码,并缓存此机器代码以在下次调用方法时使用。 (这称为Just In Time,或JIT编译,或者通常只是Jitting。)
当程序集运行时,运行时继续提供安全性,内存管理,线程等服务。应用程序由运行时管理。
Visual Basic .NET和C#只能生成托管代码。如果您正在使用这些应用程序,那么您正在制作托管代码。如果您愿意,Visual C ++ .NET可以生成托管代码:创建项目时,选择一个名称以.Managed开头的应用程序类型,例如.Managed C ++ application ..
非托管代码是您在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。尝试在非托管exe上指向ildasm,你会被告知它没有有效的CLR(公共语言运行时)标头,不能被反汇编 - 相同的扩展名,完全不同的文件。
短语本机代码用于两个上下文中。许多人将它用作非托管代码的同义词:使用旧工具构建的代码,或在Visual C ++中故意选择的代码,它不在运行时运行,而是在机器上本机运行。这可能是一个完整的应用程序,或者它可能是使用COM Interop或PInvoke从托管代码调用的COM组件或DLL,这两个强大的工具可确保您在迁移到新世界时可以使用旧代码。我更喜欢说.unmanaged代码。对于这个含义,因为它强调代码不能获得运行时的服务。例如,托管代码中的代码访问安全性可防止从其他服务器加载的代码执行某些破坏性操作。如果您的应用程序调用从另一台服务器加载的非托管代码,您将无法获得该保护。
短语本机代码的另一个用途是描述JIT编译器的输出,即在运行时实际运行的机器代码。它是管理的,但它不是CIL,它是机器代码。因此,不要只假设native = unmanaged。
(Source)
答案 1 :(得分:7)
这可能是一个很长的答案,谈论C编译器生成的机器代码与JIT编译器从托管程序生成的机器代码之间的许多细微差别。足够长,真的需要一本书,但这些书已经写好了。杰弗里里希特的任何东西。例如。
我会保持简短和活泼,因为所有这些微妙的差异归结为一个规则:
托管代码是从垃圾回收堆中分配内存的代码。
答案 2 :(得分:1)
与通常编写良好的非托管(本机)代码相比,通常托管代码具有更高的运行时内存占用量。
答案 3 :(得分:1)
托管代码在Application Domain中运行,而非托管代码在操作系统的进程下运行。
答案 4 :(得分:1)
非托管代码:-
1。该代码是在.NET Framework外部开发的,被称为非托管代码。
2。那些不在CLR控制下运行的应用程序被称为不受管理的,某些语言(例如C ++)可用于编写此类应用程序,例如,这些应用程序可访问操作系统的低级功能。 。与VB,ASP和COM代码的后台兼容性是非托管代码的示例。
3。非托管代码在包装类的帮助下执行。
4。包装器类有两种类型:CCW(COM可调用包装器)和RCW(运行时可调用包装器)。
5.Wrapper用于在CCW和RCW的帮助下弥补差异。 托管代码 在您的应用程序域中使用的资源是托管代码。域中的资源更快。
托管代码 1.在.NET框架中开发的代码称为托管代码。 该代码由CLR在托管代码执行的帮助下直接执行。用.NET Framework编写的任何语言都是托管代码。
2。托管代码使用CLR,该CLR依次通过管理内存,处理安全性,允许跨语言调试等来照看您的应用程序。
答案 5 :(得分:0)
直接在操作系统下运行的应用程序称为
未托管应用
而在.net框架下运行的应用程序称为
托管应用