System.Drawing和垃圾回收

3

如一些人所知,我最近在我的网站上发现了高内存使用率的问题。我有一个想法,可能是我的缩略图生成器与此有关,因为我不知道该如何主动处理实例的释放,导致了我的误解。

现在我正在查看我的缩略图生成器代码,并希望得到一些关于什么情况下需要进行处理释放的建议,是否仅在创建对象的新实例时才需要这样做?

比如:

Target := System.Drawing.Bitmap.Create(Trunc(Width), Trunc(Height));
MyImage := Target.FromFile(PhotoPath);

所以,我的问题是,我需要处理Target和MyImage来确保垃圾回收器能够正常工作吗?
谢谢。

System.Drawing.Bitmap 中没有 Create 方法。你具体调用的是什么? - Steven
代码是用Delphi编写的(我们公司的软件也是用Delphi编写的,因此Web版本也是如此),在C#中等效的代码为System.Drawing.Bitmap Target = new System.Drawing.Bitmap(Width, Height); - webnoob
5个回答

5

谢谢提供链接,已经打印并阅读。在过去的几天里,我从Tess那里学到了很多东西。这篇文章回答了我所有的问题。谢谢。 - webnoob

4
作为一般原则,我建议将问题反过来考虑:
是否有任何理由不处理这些特定对象?
如果类实现了IDisposable接口,那么你就需要处理它。
在许多情况下,即使在处理对象时它并没有做太多事情,但这并不意味着你不应该调用Dispose。如果你升级到新的.NET运行时版本,那可能会发生改变。
好的,让我澄清一下我的话。
当然,我并不是说你应该只对所有实现IDisposable接口的对象都调用Dispose。问题是,这个对象是不是你的。如果是你构造的,那么这是你的责任。
如果你得到了这个对象,假设它不是你的,除非你明确要求给予这个对象,而不仅仅是暂时借给你。
当然还有其他例外,但通常情况下,你拥有并实现了IDisposable接口的对象,在使用完后就需要进行Dispose处理。

3
但是每个规则都有例外。在OnPaint函数中传递给你的Graphics对象不应该被销毁。最好的经验法则是:“如果你从=得到它,就要销毁它。如果它是作为函数参数传递给你的,就不要去管它”。 - Scott Chamberlain
2
这都与所有权有关。问题是,“我是该对象的所有者(通常是创建者)”。 - Steven

2

Image实现了可处理接口。当您完成使用图片时,应该对其进行处理。对于图片来说,释放它们非常重要。它们分配了少量托管内存,但引用了大块本地内存。


提高了内存分配点;从我的阅读来看,本地内存似乎是高内存和图像的罪魁祸首,这就解释了为什么。谢谢。 - webnoob

2
是的,这两个调用都会创建新的Bitmap对象,所以在完成使用后需要将它们处理掉。
你还应该知道,你可能正在使用的其他与图形相关的对象也需要被处理掉,比如GraphicsBrushFont

1

是的,请释放您创建的IDisposable。特别是在GDI+中。

最好使用using() {}代码块。

using (Pen p = new Pen(Colors.Blue))  // Dispose this pen
{
    Brush b = Brushes.Green; // but not this Brush
    ....
}

很想尝试,但是在Delphi中没有找到相应的等价物...迫不及待地期望将引擎重写为C# :) - webnoob
Delphi 8 - Delphi2006确实有Using块,对吧?我不知道基于Chrome的版本。但是Using只是try-finally的简写形式,你们是有这个的。 - H H

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接