简体   繁体   English

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

[英]What is the difference in managed and unmanaged code, memory and size?

After seeing and listening a lot regarding managed and unmanaged code, and knowing the only difference is that managed is about CLR and un-managed is outside of the CLR, it makes me really curious to know it in detail. 在看到和听取很多关于托管和非托管代码之后,并且知道唯一的区别是托管是关于CLR而非托管是在CLR之外,这让我非常好奇地了解它。 What is it all about, managed and unmanaged code, memory and size? 它是什么,托管和非托管代码,内存和大小?

How can code I write in C# be unmanaged while this is C# code and how does a memory of size becomes unmanaged. 我在C#中编写的代码如何是非托管的,而这是C#代码,以及大小的内存如何变得不受管理。 An example and a little insight would be helpful. 一个例子和一点点见解会有所帮助。

Short answer: 简短回答:

  • Managed code is .NET code (VB.NET, C# etc.) that you write and compile to .NET CIL . 托管代码是您编写并编译为.NET CIL的 .NET代码(VB.NET,C#等)。
  • Unmanaged code is code that is not under .NET that compiles to direct machine code. 非托管代码是不在.NET下编译为直接机器代码的代码。

Long answer: 答案很长:

What Is Managed Code? 什么是托管代码?

Managed Code is what Visual Basic .NET and C# compilers create. 托管代码是Visual Basic .NET和C#编译器创建的代码。 It compiles to Intermediate Language (IL), not to machine code that could run directly on your computer. 它编译为中间语言(IL),而不是编译可以直接在您的计算机上运行的代码。 The CIL is kept in a file called an assembly, along with metadata that describes the classes, methods, and attributes (such as security requirements) of the code you've created. CIL保存在一个名为程序集的文件中,同时还包含描述您创建的代码的类,方法和属性(如安全性要求)的元数据。 This assembly is the one-stop-shopping unit of deployment in the .NET world. 这个程序集是.NET世界中部署的一站式购物单元。 You copy it to another server to deploy the assembly there—and often that copying is the only step required in the deployment. 您将其复制到另一台服务器以在那里部署程序集 - 通常复制是部署中唯一需要的步骤。

Managed code runs in the Common Language Runtime. 托管代码在公共语言运行时中运行。 The runtime offers a wide variety of services to your running code. 运行时为运行的代码提供各种服务。 In the usual course of events, it first loads and verifies the assembly to make sure the CIL is okay. 在通常的事件过程中,它首先加载并验证程序集以确保CIL正常。 Then, just in time, as methods are called, the runtime arranges for them to be compiled to machine code suitable for the machine the assembly is running on, and caches this machine code to be used the next time the method is called. 然后,就在调用方法时,运行时会安排将它们编译为适合运行程序集的机器的机器代码,并缓存此机器代码以在下次调用方法时使用。 (This is called Just In Time, or JIT compiling, or often just Jitting.) (这称为Just In Time,或JIT编译,或者通常只是Jitting。)

As the assembly runs, the runtime continues to provide services such as security, memory management, threading, and the like. 随着程序集的运行,运行时继续提供诸如安全性,内存管理,线程等服务。 The application is managed by the runtime. 应用程序由运行时管理。

Visual Basic .NET and C# can produce only managed code. Visual Basic .NET和C#只能生成托管代码。 If you're working with those applications, you are making managed code. 如果您正在使用这些应用程序,那么您正在制作托管代码。 Visual C++ .NET can produce managed code if you like: When you create a project, select one of the application types whose name starts with .Managed., such as .Managed C++ application.. 如果您愿意,Visual C ++ .NET可以生成托管代码:创建项目时,选择名称以.Managed。开头的应用程序类型之一,例如.Managed C ++应用程序。

What Is Unmanaged Code? 什么是非托管代码?

Unmanaged code is what you use to make before Visual Studio .NET 2002 was released. 非托管代码是您在Visual Studio .NET 2002发布之前使用的代码。 Visual Basic 6, Visual C++ 6, heck, even that 15-year old C compiler you may still have kicking around on your hard drive all produced unmanaged code. Visual Basic 6,Visual C ++ 6,哎呀,即使是15年前的C编译器,你可能仍然在你的硬盘驱动器上所有产生的非托管代码。 It compiled directly to machine code that ran on the machine where you compiled it—and on other machines as long as they had the same chip, or nearly the same. 它直接编译为在您编译它的机器上运行的机器代码,并且只要它们具有相同的芯片或几乎相同,就可以在其他机器上编译。 It didn't get services such as security or memory management from an invisible runtime; 它没有从不可见的运行时获得安全性或内存管理等服务; it got them from the operating system. 它从操作系统中获取它们。 And importantly, it got them from the operating system explicitly, by asking for them, usually by calling an API provided in the Windows SDK. 而且重要的是,它通过调用Windows SDK中提供的API,通过询问它们来明确地从操作系统中获取它们。 More recent unmanaged applications got operating system services through COM calls. 最近的非托管应用程序通过COM调用获得了操作系统服务。

Unlike the other Microsoft languages in Visual Studio, Visual C++ can create unmanaged applications. 与Visual Studio中的其他Microsoft语言不同,Visual C ++可以创建非托管应用程序。 When you create a project and select an application type whose name starts with MFC, ATL, or Win32, you're creating an unmanaged application. 当您创建项目并选择名称以MFC,ATL或Win32开头的应用程序类型时,您将创建一个非托管应用程序。

This can lead to some confusion: When you create a .Managed C++ application., the build product is an assembly of CIL with an .exe extension. 这可能会导致一些混淆:当您创建.Managed C ++应用程序时,构建产品是具有.exe扩展名的CIL程序集。 When you create an MFC application, the build product is a Windows executable file of native code, also with an .exe extension. 创建MFC应用程序时,构建产品是本机代码的Windows可执行文件,也具有.exe扩展名。 The internal layout of the two files is utterly different. 两个文件的内部布局完全不同。 You can use the Intermediate Language Disassembler, ildasm, to look inside an assembly and see the metadata and CIL. 您可以使用中间语言反汇编程序ildasm查看程序集内部并查看元数据和CIL。 Try pointing ildasm at an unmanaged exe and you'll be told it has no valid CLR (Common Language Runtime) header and can't be disassembled—Same extension, completely different files. 尝试将ildasm指向一个非托管的exe,你会被告知它没有有效的CLR(公共语言运行时)标头,并且不能被反汇编 - 相同的扩展名,完全不同的文件。

What about Native Code? Native Code怎么样?

The phrase native code is used in two contexts. 短语本机代码用于两个上下文中。 Many people use it as a synonym for unmanaged code: code built with an older tool, or deliberately chosen in Visual C++, that does not run in the runtime, but instead runs natively on the machine. 许多人将它用作非托管代码的同义词:使用旧工具构建的代码,或在Visual C ++中故意选择的代码,它不在运行时运行,而是在机器上本机运行。 This might be a complete application, or it might be a COM component or DLL that is being called from managed code using COM Interop or PInvoke, two powerful tools that make sure you can use your old code when you move to the new world. 这可能是一个完整的应用程序,或者它可能是使用COM Interop或PInvoke从托管代码调用的COM组件或DLL,这两个强大的工具可确保您在迁移到新世界时可以使用旧代码。 I prefer to say .unmanaged code. 我更喜欢说.unmanaged代码。 for this meaning, because it emphasizes that the code does not get the services of the runtime. 对于这个含义,因为它强调代码不能获得运行时的服务。 For example, Code Access Security in managed code prevents code loaded from another server from performing certain destructive actions. 例如,托管代码中的代码访问安全性可防止从其他服务器加载的代码执行某些破坏性操作。 If your application calls out to unmanaged code loaded from another server, you won't get that protection. 如果您的应用程序调用从另一台服务器加载的非托管代码,您将无法获得该保护。

The other use of the phrase native code is to describe the output of the JIT compiler, the machine code that actually runs in the runtime. 短语本机代码的另一个用途是描述JIT编译器的输出,即在运行时实际运行的机器代码。 It's managed, but it's not CIL, it's machine code. 它是管理的,但它不是CIL,它是机器代码。 As a result, don't just assume that native = unmanaged. 因此,不要只假设native = unmanaged。

( Source ) 来源

This could be a very long answer, talking about the many subtle differences between machine code generated by a C compiler vs the machine code generated by the JIT compiler from a managed program. 这可能是一个很长的答案,讨论C编译器生成的机器代码与JIT编译器从托管程序生成的机器代码之间的许多细微差别。 Long enough to really require a book, but such books have already been written. 足够长,真的需要一本书,但这些书已经写好了。 Anything by Jeffrey Richter for example. 杰弗里里希特的任何东西。

I'll keep it short and snappy, because all those subtle differences boil down to the One Rule: 我会保持简短和活泼,因为所有这些微妙的差异归结为一个规则:

Managed code is code that allocates memory from the garbage collected heap. 托管代码是从垃圾收集堆中分配内存的代码。

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

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

Apps Which is directly run under the OS are known as 在OS下直接运行的应用程序称为

un-managed apps 未托管的应用

whereas apps which run under the .net framework are known as 而在.net框架下运行的应用程序被称为

managed apps 托管应用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM