在.Net C中释放资源#

我是C#和.NET的新手,并且一直在阅读它。

我需要知道为什么以及何时需要释放资源? 垃圾收集器不能处理所有事情吗? 我什么时候需要实现IDisposable,它与C ++中的析构函数有什么不同?

此外,如果我的程序相当小,即屏幕保护程序,我是否需要关心释放资源?

谢谢。

基本上,您需要担心将资源释放到非托管代码 – .NET框架之外的任何内容。 例如,OS上的数据库连接或文件。

垃圾收集器处理托管代码 – .NET框架中的代码。

即使是小型应用程序也可能需要释放非托管资源,例如它可能会写入本地文本文件。 完成资源后,需要确保调用对象的Dispose方法。 using语句简化了语法:

using (TextWriter w = File.CreateText("test.txt")) { w.WriteLine("Test Line 1"); } 

TextWriter对象实现了IDisposable接口,因此一旦使用块完成,就会调用Dispose方法并且可以对对象进行垃圾回收。 收集的实际时间无法保证。

如果您创建自己需要正确处理的类,则需要自己实现IDisposable接口和Dispose模式。 在一个简单的应用程序中,您可能不需要这样做,如果您这样做是一个很好的资源。

垃圾收集器只知道内存。 这对内存来说很好,因为只要你有足够的内存,一点内存几乎和其他内存一样好。 (这是所有模缓存一致性等)

现在将其与文件句柄进行比较。 操作系统可以有足够的空间来分配更多的文件句柄 – 但是如果你留下一个特定文件的句柄,那么其他任何人都无法打开该特定文件进行写入。 一旦完成,您应该告诉系统何时完成一个句柄 – 通常是通过关闭相关的流 – 并且即使抛出exception也会以关闭它的方式执行此操作。 这通常using语句来完成,这类似于try / finally,在finally块中调用Dispose

C ++中的析构函数与.NET终结函数非常不同,因为C ++析构函数是确定性的 – 例如,当相关变量超出范围时,它们会自动调用。 任何“实时”对象不再引用对象之后的某个时刻 ,终结器由垃圾收集器运行,但时间是不可预测的。 (在极少数情况下,它可能永远不会发生。)

如果你有任何清理应该确定性地执行,你应该自己实现IDisposable – 通常情况下,如果你的一个实例变量实现了IDisposable 。 现在很少需要自己实现终结器 – 如果你直接持有操作系统句柄,通常只需要一个,通常是以IntPtr的forms; SafeHandle使所有这一切变得更加容易,让您不必自己编写终结器。

资源有两种 – 托管和非托管。 如果你允许,垃圾收集器将清理托管资源 – 也就是说,如果你释放对该对象的任何引用。 但是,垃圾收集不知道如何释放托管对象保存的非托管资源 – 文件句柄和其他OS资源。

当您希望及时发布托管资源(如数据库连接)时,IDisposable是最佳实践,而当您需要释放非托管资源时,IDisposable至关重要。 典型模式:

 public void Dispose() protected void Dispose(bool disposing) 

允许您确保通过Dispose方法或对象终结来释放非托管资源。

您不需要在托管对象(如字符串或数组)中释放内存 – 这是由垃圾收集器处理的。

完成使用后,应清理操作系统资源和一些非托管对象。 如果您打开文件,则应始终记得在使用完毕后关闭该文件。 如果您专门打开文件而忘记关闭,则下次尝试打开该文件时,它可能仍会被锁定。 如果某些东西实现了IDisposable ,你一定要考虑是否需要正确关闭它。 文档通常会告诉您Dispose方法的作用以及何时应该调用它。

如果你忘记了,垃圾收集器最终会运行终结器,它应该正确清理对象并释放非托管资源,但这不会在对象符合垃圾收集条件后立即发生,事实上它根本不会运行。

了解using语句也很有using

垃圾收集器释放MEMORY并清理 – 通过处置 – 它删除elemet。 但是:只有在内存压力下才会这样做。

对于我可能想要明确释放它们的资源来说,这是非常愚蠢的。 例如,保存到文件应该是:打开文件,写出数据并 – 关闭文件,这样如果用户可以将其复制掉,而无需等待GC出现并释放内存对于文件对象,这可能不会发生几个小时。

你只需要担心宝贵的资源。 您在编程时创建的大多数对象都不适合此类别。 如你所说,垃圾收集器将负责这些。

您需要注意的是实现IDisposable的对象,这表明它拥有的资源是宝贵的,不应该等待清理终结器线程。 您需要实现IDisposable的唯一时间是拥有a)实现IDisposable的对象(例如文件流)或b)非托管资源的类。