首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >处理SolidBrush和笔很重要吗?

处理SolidBrush和笔很重要吗?
EN

Stack Overflow用户
提问于 2009-11-30 18:51:07
回答 6查看 5.6K关注 0票数 18

我最近遇到了this VerticalLabel control on CodeProject

我注意到OnPaint方法创建了Pen和SolidBrush对象,但没有处理它们。

这很重要吗?如果是这样,我该如何演示它可能导致的问题?

编辑

一般来说,这不是一个关于IDisposable模式的问题。我知道调用者通常应该在任何实现IDisposable的类上调用Dispose。

我想知道的是,当不像上面的例子那样释放GDI+对象时,可能会出现什么问题(如果有的话)。很明显,在链接的示例中,在垃圾收集器启动之前可能会多次调用OnPaint,因此有可能会用完句柄。

然而,我怀疑GDI+在某些情况下会在内部重用句柄(例如,如果您使用来自Pens类的特定颜色的笔,它将被缓存和重用)。

我试图理解的是,像链接示例中那样的代码是否能够在忽略调用Dispose的情况下逃脱惩罚。

如果不是,请看一个示例,演示它可能导致的问题。

我应该补充的是,我经常(在including the OnPaint documentation on MSDN)看到WinForms代码示例无法处理GDI+对象。

EN

回答 6

Stack Overflow用户

发布于 2009-11-30 18:58:03

当然,这很重要。当不再需要实现IDisposable的类的所有实例时,将其释放是很重要的。类在使用非托管资源(即不是由.NET框架处理的操作系统资源)时被定义为IDisposable。

如果您不手动释放这些对象,那么在垃圾收集器调用对象终结器之前,这些非托管资源将不会被释放(这只会在类正确实现the Dispose pattern的情况下发生),这可能会很晚,因为垃圾收集器仅在检测到实际内存不足时才会运行。因此,当不释放对象时,您将保留原本可供其他应用程序使用的操作系统资源。

关于这个主题的讨论可以在这里找到:http://agilology.blogspot.com/2009/01/why-dispose-is-necessary-and-other.html

票数 5
EN

Stack Overflow用户

发布于 2010-11-10 07:20:07

顺便说一句,在GDI中有“股票”对象。当你创建一个股票对象时,你不必删除它,因为它是由操作系统“拥有”的。

您可能已经了解了股票对象,但这里有一个详细介绍的link

我不知道GDI+中是否有类似的“股票”对象。我只是简单地搜索了一下,还没有找到任何这样的引用。

作为测试,我编写了一个带有计时器回调(设置为每10毫秒触发一次)的小WinForms程序,如下所示:

代码语言:javascript
复制
private void timer1_Tick(object sender, EventArgs e)
{
  byte r = (byte)rnd.Next(0, 256);
  byte g = (byte)rnd.Next(0, 256);
  byte b = (byte)rnd.Next(0, 256);

  System.Drawing.SolidBrush sb = new SolidBrush(Color.FromArgb(0,r,g,b));
}

如果我让它运行,它会慢慢地消耗内存。通过观察TaskManager (不是衡量它的最准确的方法),内存使用倾向于增长(在我的机器上,使用.NET 4.0 VS2010,发行版),每次任务管理器更新大约20k字节(以最高的更新率)。如果我在画笔上调用Dispose,则每次任务管理器更新时,内存使用量往往会增加约8k。

这几乎不是一个明确的测试,但它似乎表明,如果不释放SolidBrush,随着时间的推移,内存使用量会更大。有趣的是,在测试运行时(无论是哪种情况),我既没有增加句柄,也没有增加GDI对象。根据过去GDI资源泄漏的经验,我预计可能会看到GDI对象增长,特别是在非Dispose情况下。

无论如何,这可能是信息性的,也可能不是。

票数 5
EN

Stack Overflow用户

发布于 2012-08-13 19:45:51

我需要修复应用程序中的一些内存泄漏,所以我一直在做一些调查。简而言之,似乎在大多数情况下,您可以在稍微高一点的内存使用量的情况下逃脱惩罚。

下面是一个病理性的案例。我在任务管理器(我知道的很粗糙)中监控我的测试应用程序,并查看Memory (私有工作集)、Handles、USER Objects和GDI Objects列。与Button2单击相比,Button1单击会导致更高的内存使用率。

如果我快速并持续地点击Button1,当内存达到1.6 If时,我可能会导致'System.OutOfMemoryException‘。无论我如何疯狂或持续地点击,Button2都不会超过12MB。

我在一台win7 64位机器上构建了一个VS2010 .net 4客户端配置文件winforms应用程序。很明显,你通常不会构建成千上万的笔刷...

向David致敬

代码语言:javascript
复制
private void button1_Click(object sender, EventArgs e) {
    for (int i = 0; i < 500000; i++) {
        SolidBrush b = new SolidBrush(Color.FromArgb(2, 32, 43, 128));
    }       
}

private void button2_Click(object sender, EventArgs e) {
    for (int i = 0; i < 500000; i++) {
        using (SolidBrush b = new SolidBrush(Color.FromArgb(2, 32, 43, 128))) {
        }
    }
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1819096

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档