GC和IDispose如何在C#中工作?

我记得我是通过将它从网络直接流式传输到位图来加载图像。 关闭流,返回位图并将其保存在图像控件中。

我除了当我执行= loadPicture()时,第一个位图将被释放,就像智能​​指针在C ++中一样。 但它没有,我消耗了大量的公羊,直到我打电话给处理。 所以我的问题是。

GC和Dispose能够如何在C#中工作? 为什么它不像smart_ptr那样实现?

引用不是智能指针。 让引用变量超出范围,将其替换为另一个值,和/或将其设置为null都不会执行任何操作

这只是CLI / GC设计的一部分……

Gargage Collection(GC)将在需要时运行,并且应该清理所使用的托管内存,并且(如果提供了终结器)也可以清除任何非托管资源。 但对于确定性清理:这就是IDisposable的全部目的。 当你完成它们时, Dispose()这些对象是你的工作 – 通过using ,或者把它交给承担这个责任的其他东西(常见的,例如,使用流/读者等)。

 using (StreamReader reader = new StreamReader(myfile))) { ... } 

当运行时觉得有必要时,GC就会启动。

基本规则是:当您使用Disposable类型(IDispose)时,您(作为程序员)应该尽快释放该类型使用的资源,通过在不再需要使用该类型时调用Dispose。 例如,当您读取文件时,您在阅读完文件后立即关闭该文件。 (在这种情况下,呼叫关闭也会调用dispose)。

您必须在实现IDisposable的任何对象上调用Dispose explicity,否则将不会处理您的非托管资源。 如果您不想将其称为明确,那么您必须覆盖Finalize方法以调用Dispose方法 – 这就是为什么您会经常看到这个:

  class MyClass : IDisposable { ... ~MyClass() { this.Dispose(false); } public void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (disposing) { /* dispose managed stuff also */ } /* but dispose unmanaged stuff always */ } } 

smart_ptr是引用计数。 虽然当它们不再被任何代码引用时允许确定性地释放它们的资源,但它们确实存在它们自己的问题:分配引用总是需要更新计数器,循环引用无法自动释放导致内存泄漏,内存管理器被更频繁地调用。

.NET中的GC是一个全面的收集器。 它始于任何时候它感觉应该释放内存(通常由一些内存使用情况触发,但不是确定性),并通过构建系统中所有实时引用的列表开始(包括CPU寄存器中的内容,嵌套引用等) )。 这是有效的,因为我们处于无法进行指针运算等的托管环境中 – 系统可以跟踪所有引用。 在构建了实时引用列表之后,它基本上释放了所有未知的内存。 当然,这只是基本的草图,对于非托管资源的效率和管理,它更像是对象生成,终结器等,但这对于它如何工作的基本理解并不重要。

IDisposable接口用于实现一次性模式,这有助于在处理应以确定方式处置的对象时使用。 该模式是在不再需要对象时显式调用Dispose(),因此释放非托管资源或关闭句柄等,但不释放其内存。 这将在稍后由GC完成,但是后来发生这种情况并不重要,因为已经执行了资源的确定性释放。