.NET中"托管"与"非托管"资源的含义是什么?

Red*_*wan 103 .net c# unmanaged managed

.NET中托管资源和非托管资源的含义是什么意思?他们是如何进入画面的?

Rob*_*Rob 71

术语"非托管资源"通常用于描述不直接受垃圾收集器控制的内容.例如,如果打开与数据库服务器的连接,则将使用服务器上的资源(用于维护连接)以及客户端计算机上的其他非.NET资源(如果提供程序不是完全使用托管代码编写的话).

这就是为什么,对于像数据库连接这样的东西,建议你这样写代码:

using (var connection = new SqlConnection("connection_string_here"))
{
    // Code to use connection here
}
Run Code Online (Sandbox Code Playgroud)

这样可以确保.Dispose()在连接对象上调用,确保清除所有非托管资源.

  • 我稍微澄清一下:如果垃圾收集器被废弃,那么垃圾收集器就不会知道如何清理它.例如,短期对象对来自长期存在的对象的事件的订阅将是非托管资源,即使两个对象都在垃圾收集器的控制之下,因为GC将无法知道订阅如果订阅者被放弃但发布者不被放弃,则应该废弃.如果在发布者的生命周期内可以创建和放弃无限数量的订阅者,则会导致内存泄漏. (17认同)
  • 更进一步说明:SqlConnection(或FileStream等)是托管资源,内部使用GC不知道的非托管资源. (11认同)
  • jimvfr 是对的,SqlConnection 就是一个托管资源的例子。非托管资源的一个例子是,当我们需要使用 Marshal.AllocHGlobal() 方法从非托管内存分配内存时,它是非托管资源,在这种情况下,最佳实践是使用析构函数(~ctor)并调用 Marshal.FreeHGlobal()释放这段记忆。 (2认同)

Ode*_*ded 30

托管资源是那些纯.NET代码并由运行时管理并受其直接控制的资源.

非托管资源是那些不受管理的资源.文件句柄,固定内存,COM对象,数据库连接等.


Dav*_*dRR 10

在问答中什么是非托管资源?1,Bruce Wood发布了以下内容:

我这样想到"托管"和"非托管"这两个术语:

"托管"是指.NET沙箱中的任何内容.这包括所有.NET Framework类.

"非托管"是指.NET沙箱之外的荒野.这包括通过调用Win32 API函数返回给您的任何内容.

如果您从未调用Win32 API函数并且永远不会返回任何Win32"句柄"对象,那么您不会持有任何非托管资源.通过.NET Framework类方法打开的文件和流都是托管包装器.

评论:您可能没有持有非托管资源直接.但是,您可能通过托管的"包装类"(如System.IO.FileStream)间接持有非托管资源.这样的包装类通常实现IDisposable(直接或通过继承).

...许多托管(.NET Framework)对象都在其中包含非托管资源,您可能希望尽快Dispose(),或者至少为您的调用者提供这样做的机会.这就是编写自己的Dispose()方法的地方.实际上,实现IDisposable()会为你做两件事:

  1. 允许您从.NET背面的操作系统(非托管资源)中删除您直接获取的任何资源.

  2. 允许您和您的呼叫者释放大量的.NET对象/ .NET对象,这些对象在您/您的呼叫者现在要释放的肮脏的小手中拥有宝贵的资源.

注释:通过实现IDisposable并从而提供Dispose()方法,您可以使您的类的用户以确定的方式释放由您的类实例持有的任何非托管资源.


1链接最初在Sachin Shanbhag的回答中分享.引用的材料日期为2005-11-17.请注意,我对引用的内容进行了轻微的复制编辑.


Sac*_*hag 5

托管和非托管资源之间的基本区别在于垃圾收集器知道所有托管资源,在某个时间点GC将出现并清理与托管对象关联的所有内存和资源.GC不知道非托管资源,例如文件,流和句柄,因此如果您不在代码中明确清除它们,那么最终会导致内存泄漏和锁定资源.

有关详细信息,请访问:http://bytes.com/topic/c-sharp/answers/276059-what-unmanaged-resources

  • “IDisposable 接口背后的想法是让您以确定性方式清理资源并清理非托管资源。”太棒了! (2认同)