C#中有哪些资源需要手动清理?不进行清理会有什么后果?
例如,假设我有以下代码:
myBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Black);
// Use Brush
如果我不使用 dispose 方法清除刷子,我是否假定垃圾回收器会在程序终止时释放使用的内存?这个说法正确吗?
还需要哪些资源来手动清理?
C#中有哪些资源需要手动清理?不进行清理会有什么后果?
例如,假设我有以下代码:
myBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Black);
// Use Brush
如果我不使用 dispose 方法清除刷子,我是否假定垃圾回收器会在程序终止时释放使用的内存?这个说法正确吗?
还需要哪些资源来手动清理?
类似这样的内容还有很多。
调用Dispose
方法非常重要,甚至更好的做法是使用using
模式。
using (SolidBrush myBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Black))
{
// use myBrush
}
如果你不释放某个对象,它会在垃圾回收器注意到没有对它的引用时被清除,这可能需要一些时间。
对于System.Drawing.Brush
,Windows会保留其内部窗口结构的加载直至所有程序都释放了其句柄。
using (SolidBrush myBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Black))
{
// use myBrush
}
不正确地处理IDisposable对象可能导致应用程序性能受损,甚至崩溃。
在您的示例中,Brush对象将在GC感觉合适时进行清理。但是,如果您提前清理它,您的程序将无法获得额外内存的好处。如果您正在使用大量Brush对象,则这可能变得重要。GC还更有效地清理对象,如果它们没有存在很长时间,因为它是一种分代垃圾回收器。
另一方面,不正确地处理数据库连接对象可能意味着您很快就会耗尽池化数据库连接并导致应用程序崩溃。
要么使用
using (new DisposableThing...
{
...
}
或者,如果您需要在对象的生命周期内保留对IDisposable的引用,请在对象上实现IDisposable并调用IDisposable的Dispose方法。
class MyClass : IDisposable
{
private IDisposable disposableThing;
public void DoStuffThatRequiresHavingAReferenceToDisposableThing() { ... }
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
//etc... (see IDisposable on msdn)
}
通常,任何实现IDisposable接口的内容都应该让你停下来,研究一下你正在使用的资源。
垃圾回收只会在有内存压力时发生,因此您无法预测什么时候会发生。虽然卸载AppDomain肯定会触发它。
从技术上讲,任何继承自IDisposable的东西都应该被主动处理。您可以使用'using'语句使事情变得更容易。
http://msdn.microsoft.com/en-us/library/yh598w02.aspx
有时候你会在文档示例代码以及工具生成的代码(比如 Visual Studio)中看到 IDisposable 派生对象的不一致使用。MemoryStream ms = new MemoryStream().Dispose
using(MemoryStream ms = new MemoryStream())
{
...
}
只要您使用托管版本的资源并且不自己调用Windows API,那么就应该没问题。唯一需要担心的是当您获得一个IntPtr时需要删除/销毁资源,因为在.NET中,“Windows句柄”(以及许多其他内容)是已知的,而不是对象。
顺便说一下,资源(像任何其他.NET对象一样)将在您离开当前上下文时被标记为可回收,因此如果您在方法内部创建Brush,则在退出方法时它将被标记。
如果它是托管的(即框架的一部分),您不需要担心它。如果它实现了IDisposable接口,只需将其包装在using
块中即可。
如果您想使用非托管资源,则需要了解有关终结器和自己实现IDisposable的更多信息。
有关更多详细信息,请参见此问题。