被管理的资源基本上指的是由垃圾收集器管理的"受管内存"。当你不再引用使用受控内存的管理对象时,垃圾回收器将(最终)释放该内存。
未被管理的资源是垃圾收集器不知道的所有内容。例如:
通常在失去对管理它们的对象的所有引用之前,您希望释放这些未被管理的资源。通过调用该对象上的Dispose
或(在C#中)使用using
语句来处理为您调用Dispose
。
如果您没有正确地Dispose
未经管理的资源,则垃圾回收器最终将在包含该资源的对象被垃圾回收时为您处理它(这是“终结”)。但是,由于垃圾回收器不知道未经管理的资源,因此它无法告诉自己需要多么严重地释放它们-因此,您的程序可能表现不佳或完全耗尽资源。
如果您自己实现了处理未经管理的资源的类,则由您负责正确实现Dispose
和Finalize
。
Dispose
或使用using
的位置。 - Andrew RussellIDisposable
接口。如果一个类确实实现了IDisposable
接口,那么在使用完这些实例后,你应该使用 using
或 Dispose()
进行释放。基于此,你可以得出相反的结论:如果一个类实现了 IDisposable
接口,那么它很可能在内部持有非托管资源。 - Andrew Russell使用这些包装器时,您也有责任。对于那些实现了 dispose/finalize(您可以通过它们是否实现 IDisposable 接口来识别它们)的包装器,请实现自己的 dispose/finalize 模式,并在销毁这些包装器时调用它们的 Dispose 方法或者给它们发送信号以释放它们的非托管资源。如果不这样做,这些资源将在一段不确定的时间后被释放,但最好立即释放它们(立即关闭文件而不是让它保持打开状态并占据几分钟/几小时)。因此,在您的类的 Dispose 方法中,调用所有已使用包装器的 Dispose 方法。
未托管资源是指在.NET运行时(CLR)之外运行的资源(也称非.NET代码)。例如,调用Win32 API中的DLL或调用用C++编写的.dll。
.NET应用程序被编译成中间语言(IL)。IL也被称为公共中间语言(CIL)和Microsoft中间语言(MSIL)。.NET和非.NET应用程序都会生成一个程序集。程序集的扩展名为.DLL或.EXE。例如,如果您编译Windows或控制台应用程序,您将得到一个.EXE文件,而当我们编译Web或类库项目时,我们得到一个.DLL文件。.NET程序集与非.NET程序集之间的区别在于,DOTNET程序集是以中间语言格式存在的,而NON DOTNET程序集是以本机代码格式存在的。
NON DOTNET应用程序可以直接运行在操作系统之上,而DOTNET应用程序运行在称为公共语言运行时(CLR)的虚拟环境之上。CLR包含一个组件叫做即时编译器(JIT),它将把中间语言转换为本机代码,使底层操作系统能够理解。
因此,在.NET中,应用程序执行包括两个步骤: 1. 语言编译器将源代码编译为中间语言(IL) 2. CLR中的JIT编译器将IL转换为本机代码,然后可以在底层操作系统上运行。
由于.NET程序集(assembly)采用中间语言格式,而不是本地代码,因此只要目标平台有公共语言运行时(CLR),.NET程序集就可以在任何平台上移植。目标平台的CLR将中间语言转换为底层操作系统能够理解的本地代码。中间语言也称为托管代码,这是因为CLR管理其中运行的代码。例如,在VB6程序中,开发人员负责释放对象所占用的内存。如果程序员忘记释放内存,可能会遇到难以检测的内存溢出异常。另一方面,.NET程序员不需要担心释放对象所占用的内存。CLR提供了自动内存管理,也称为垃圾回收。除了垃圾回收外,CLR还提供了其他几个好处,我们将在后面的课程中讨论。由于CLR管理和执行中间语言(IL),因此它(IL)也被称为托管代码。非托管和受管资源都基于应用程序域
。
依据我的理解,非托管资源是指用于连接应用程序域外部
的一切资源。
例如:你使用HttpClient
类获取域外数据,或使用FileStream
读写文件。
我们使用 Using
代码块及时释放这些类对象,因为垃圾回收器(GC)
首先负责处理进程内资源而不是外部资源,虽然它最终也会将其处理掉。