如果我不在此代码段中的Dispose
对象上调用pen
会怎样?
private void panel_Paint(object sender, PaintEventArgs e)
{
var pen = Pen(Color.White, 1);
//Do some drawing
}
答案 0 :(得分:27)
答案 1 :(得分:23)
无论您是否致电Pen
,GC都会在将来的某个不确定点收集Dispose
。
但是,笔所持有的任何非托管资源(例如,GDI +句柄)都不会被GC清理。 GC仅清理托管资源。调用Pen.Dispose
可以确保及时清理这些非托管资源,并确保您不会泄漏资源。
现在,如果Pen
有一个终结器并且终结器清理了非托管资源,那么当Pen
被垃圾收集时,那些所说的非托管资源将被清除。但问题是:
Dispose
,以便释放非托管资源, Pen
实施IDisposable
。 IDisposable
用于处置非托管资源。这是.NET中的模式。
有关此主题的先前评论,请参阅此answer。
答案 2 :(得分:13)
在将来某些不确定的时间,即Pen对象被垃圾收集并且调用对象的终结器时,将不会释放底层GDI +笔柄。这可能不会在流程终止之前,或者可能更早,但重点是它是非确定性的。调用Dispose允许您进行确定性清理,强烈建议使用。
答案 3 :(得分:2)
如果您真的想知道当您不在图形对象上调用Dispose时有多糟糕,可以使用CLR Profiler,可免费下载here.在安装文件夹中(默认为C:\ CLRProfiler)是CLRProfiler.doc,它有一个很好的例子,说明当你不在Brush对象上调用Dispose时会发生什么。这很有启发性。您可能还想阅读使用IDisposable here和here。
答案 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)
在我的脑海里,第一个想法浮出水面就是这个对象将在方法完成执行后立即处理!我不知道我在哪里得到这个信息!是不是?