如果我不在笔对象上调用Dispose会发生什么?

时间:2010-11-24 14:14:03

标签: c# winforms dispose

如果我不在此代码段中的Dispose对象上调用pen会怎样?

private void panel_Paint(object sender, PaintEventArgs e)
{
    var pen = Pen(Color.White, 1);
    //Do some drawing
}

10 个答案:

答案 0 :(得分:27)

答案 1 :(得分:23)

无论您是否致电Pen,GC都会在将来的某个不确定点收集Dispose

但是,笔所持有的任何非托管资源(例如,GDI +句柄)都不会被GC清理。 GC仅清理托管资源。调用Pen.Dispose可以确保及时清理这些非托管资源,并确保您不会泄漏资源。

现在,如果Pen有一个终结器并且终结器清理了非托管资源,那么当Pen被垃圾收集时,那些所说的非托管资源将被清除。但问题是:

  1. 您应该明确调用Dispose,以便释放非托管资源,
  2. 如果有终结器并且它清理了非托管资源,您不必担心实现细节。
  3. Pen实施IDisposableIDisposable用于处置非托管资源。这是.NET中的模式。

    有关此主题的先前评论,请参阅此answer

答案 2 :(得分:13)

在将来某些不确定的时间,即Pen对象被垃圾收集并且调用对象的终结器时,将不会释放底层GDI +笔柄。这可能不会在流程终止之前,或者可能更早,但重点是它是非确定性的。调用Dispose允许您进行确定性清理,强烈建议使用。

答案 3 :(得分:2)

如果您真的想知道当您不在图形对象上调用Dispose时有多糟糕,可以使用CLR Profiler,可免费下载here.在安装文件夹中(默认为C:\ CLRProfiler)是CLRProfiler.doc,它有一个很好的例子,说明当你不在Brush对象上调用Dispose时会发生什么。这很有启发性。您可能还想阅读使用IDisposable herehere

答案 4 :(得分:2)

正在使用的.Net内存总量是.Net部分+正在使用的所有“外部”数据。操作系统对象,打开文件,数据库和网络连接都需要一些非纯粹.Net对象的资源。

图形使用笔和其他对象,这些对象实际上是非常昂贵的操作系统对象。 (您可以将笔换成1000x1000位图文件)。一旦调用特定的清理功能,这些OS对象就会从OS内存中删除。 Pen和Bitmap Dispose函数会在您调用它们时立即为您执行此操作。

如果你不调用Dispose,垃圾收集器会在将来的某个地方清理它们。 (它实际上会调用可能调用Dispose()的析构函数/终结代码)

*在未来某个地方拥有无限内存(或超过1GB)的机器上可能会非常遥远。在一台什么都不做的机器上,可以很容易地用30分钟来清理那个巨大的位图或非常小的笔。

答案 5 :(得分:1)

它将保留资源,直到垃圾收集器清理它

答案 6 :(得分:1)

取决于它是否实现了终结器并且在其finalize方法上调用Dispose。如果是这样,处理将在GC发布。

如果没有,句柄将一直存在,直到进程终止。

答案 7 :(得分:0)

使用图形内容可能非常糟糕。

打开Windows任务管理器。单击“选择列”并选择名为“GDI对象”的列。

如果您不处理某些图形对象,这个数字将继续升高和提高。

在旧版本的Windows中,这可能导致整个应用程序崩溃(据我记得限制为10000),虽然不确定Vista / 7但它仍然是一件坏事。

答案 8 :(得分:-1)

垃圾收集器无论如何都会收集它但是它很重要的时候: 如果你不打算对你不使用它的对象进行处理,那么它将在内存中存活更长时间并被提升到更高代,这意味着收集它的成本更高。

答案 9 :(得分:-3)

在我的脑海里,第一个想法浮出水面就是这个对象将在方法完成执行后立即处理!我不知道我在哪里得到这个信息!是不是?