简体   繁体   English

.NET中的托管与非托管资源。有什么不同?

[英]Managed vs Unmanaged Resources in .NET. What's the difference?

I was reading Wrox's Professional C# 4 and .NET 4 chapter on "Memory Management and Pointers", specifically about how Garbage Collection works in .NET. 我正在阅读Wrox的专业C#4和.NET 4章节“内存管理和指针”,特别是关于Garbage Collection如何在.NET中运行。 It said the reason that "the garbage collector does not know how to free unmanaged resources (such as file handles, network connections, and database connections)", which is why such classes should either declare a destructor (aka "finalizer") or implement IDisposable . 它说“垃圾收集器不知道如何释放非托管资源(例如文件句柄,网络连接和数据库连接)”的原因,这就是为什么这些类应该声明析构函数 (也称为“终结器”)或实现IDisposable

It seems like all these examples of "unmanaged resources" are related to interaction with a system that is extrinsic from the application and independent of the .NET Framework. 似乎所有这些“非托管资源”的示例都与从应用程序外部并独立于.NET Framework的系统交互相关。 However, I'm not sure if that is the complete distinction that is being made, so, 但是,我不确定这是否是正在进行的完全区分,因此,

What exactly is the distinctive characteristic that an unmanaged resource has and a managed resource doesn't have? 非托管资源和托管资源没有的独特特征究竟是什么?

You got it right: 你做对了:
Managed resources are managed by the CLR, unmanaged aren't. 托管资源由CLR管理,非托管资源不管理。 In other words: Managed resources live only in the .NET world where as unmanaged resources are from the normal Win32 world. 换句话说:托管资源仅存在于.NET世界中,而非托管资源来自正常的Win32世界。

With managed resources (ie, memory) you don't have to worry about what happens to them after you are done using them; 使用托管资源(即内存),您不必担心使用它们后会发生什么; the CLR takes care of that. CLR负责这一点。

Unmanaged resources (there are several types of these: Windows kernel objects, GDI objects, USER objects) have to be released back to the system when you are done using them . 非使用资源(有几种类型:Windows内核对象,GDI对象,USER对象) 必须在使用完后释放回系统 This happens automatically when your process terminates, but if it leaks them in the meantime you have a big problem because you are leaking resources shared among all processes in the system . 当您的进程终止时会自动发生这种情况,但如果它在此期间泄漏,则会出现一个大问题,因为您正在泄漏系统中所有进程之间共享的资源。

Of course, there are several classes in .NET that wrap these unmanaged resources (using the dispose/finalize pattern ) and do the hard work for you. 当然,.NET中有几个类包装这些非托管资源(使用dispose / finalize模式 )并为您完成艰苦的工作。 Use those if you can. 如果可以,请使用它们。

I would say that generally anything created using the .Net framework is a managed resource. 我会说,通常使用.Net框架创建的任何东西都是托管资源。 Internally they might use unmanaged resources but from your perspective they are managed. 在内部,他们可能会使用非托管资源,但从您的角度来看,他们是受管理的。 One of the exceptions to this is when you P/Invoke. 其中一个例外是你P / Invoke。 Although you create a function that works with .Net, the call gets passed outside of the .Net "sandbox" and therefor is considered unmanaged. 虽然您创建了一个与.Net一起使用的函数,但是调用会在.Net“沙箱”之外传递,因此被认为是不受管理的。

Response to @supercat 对@supercat的回应

Events from long-lived objects may be handled entirely within the .net framework, but they definitely need to be regarded as unmanaged resources to prevent memory leaks 来自长期存在的对象的事件可能完全在.net框架内处理,但它们肯定需要被视为非托管资源以防止内存泄漏

I think there's two separate things here. 我认为这里有两个不同的东西。 There's the discussion of managed vs unmanaged and there's the discussion of memory management for an application. 有关托管与非托管的讨论,并讨论了应用程序的内存管理。 You probably should treat some objects as if they were unmanaged but that doesn't mean that they are unmanaged. 您可能应该将某些对象视为不受管理,但这并不意味着它们不受管理。 For instance, the Brush class I would consider managed but you should treat it as unmanaged by calling Dispose() . 例如,我会考虑使用Brush类进行托管,但是你应该通过调用Dispose()将其视为非托管类。 Hidden/abstracted within the class are unmanaged objects that you hope Dispose() takes care of. 在类中隐藏/抽象是您希望Dispose()负责的非托管对象。 But Dispose() doesn't actually free any resourced, its just a pattern that you hope developers implement correctly. Dispose()实际上并没有释放任何资源,它只是一个你希望开发人员正确实现的模式。

To go further I would say that most unmanaged objects are created by calling a CreateXYZ() Win32 method that returns a pointer but need to be released using a `DestroyXYZ()/DeleteXYZ()' method that takes the same pointer. 为了更进一步,我想说大多数非托管对象是通过调用CreateXYZ() Win32方法创建的,该方法返回一个指针但需要使用带有相同指针的`DestroyXYZ()/ DeleteXYZ()'方法释放。 Managed objects on the other hand implement Dispose/Finalize to do this for you. 另一方面,托管对象实现Dispose / Finalize为您执行此操作。 Once again, you hope that the writers of managed resources have done this but there's no guarantee. 再一次,您希望托管资源的编写者已经做到了这一点,但并不能保证。

The term "unmanaged resource" is confusing. “非托管资源”一词令人困惑。 A more useful concept is "cleanup responsibility". 一个更有用的概念是“清理责任”。 If an object holds unmanaged resources, that means three things: 如果一个对象拥有非托管资源,那意味着三件事:

  1. It manipulates some longer-lived entity outside itself, 它操纵一些外部长寿的实体,
  2. That entity may be in a state requiring cleanup, and 该实体可能处于需要清理的状态,并且
  3. The object is responsible for providing the required cleanup 该对象负责提供所需的清理

Generally, the term "managed resource" is used to refer to objects which hold unmanaged resources, but which will receive notification from the garbage collector (via the Finalize routine) if they are found to be abandoned, and which will use such notification to provide cleanup (in case they got abandoned before their normal cleanup method was invoked). 通常,术语“受管资源”用于表示保存非托管资源的对象,但如果发现它们被放弃,它将从垃圾收集器接收通知(通过Finalize例程),并且将使用此类通知提供清理(​​如果在调用正常的清理方法之前它们被放弃了)。 Some people use the term "managed resource" to refer to things that don't require any cleanup, but I don't like such usage, since there isn't any other good term to refer to things that should be cleaned up manually but will use finalization as a fallback in case normal cleanup doesn't happen. 有些人使用术语“托管资源”来指代不需要任何清理的东西,但我不喜欢这样的用法,因为没有任何其他好的术语来指代应该手动清理的东西但是将使用finalization作为后备,以防正常清理不发生。

Note that while unmanaged resources are often things like OS handles for files, GDI entities, etc. it's a mistake to think of them in such terms. 请注意,虽然非托管资源通常是文件的OS句柄,GDI实体等,但用这样的术语来思考它们是错误的。 It's possible to have unmanaged resources which do not access anything outside the .Net framework; 可能有非托管资源不能访问.Net框架之外的任何内容; event handlers are a common example of that. 事件处理程序就是一个常见的例子。 The critical aspect of unmanaged resources is that they need cleanup, and failure to perform such cleanup will have some undesirable consequence. 非托管资源的关键方面是它们需要清理,而未能执行此类清理会产生一些不良后果。

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

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