2012-11-27 90 views
0

我有一个WPF应用程序,它在特定模式下每隔0.5秒向UI显示一个文本字符串。我注意到,当发生这种情况时,内存使用量会缓慢而稳定地增加,而这种增加是永远不会释放的,如果我让它运行足够长的时间,它将耗尽内存并崩溃。DrawingContext.DrawText是否有内存泄漏?

,做绘图的代码如下:

public void DrawDisplay(DrawingContext dc, Size size) 
{ 
    ... 

    // Draw Text 
    var fontSize = 46.0; 
    FormattedText ft = new FormattedText(
     message, 
     CultureInfo.GetCultureInfo("en-us"), 
     FlowDirection.LeftToRight, 
     new Typeface("Franklin Book"), 
     fontSize, 
     Brushes.Black); 

    ft.MaxTextWidth = size.Width - 2; 
    ft.TextAlignment = TextAlignment.Center; 

    // don't draw outside of box 
    ft.MaxTextHeight = size.Height; 

    // Center 
    var height = (size.Height - ft.Height)/2; 

    dc.DrawText(ft, new Point(0, height)); 

    ... 
}  

文字画有下面的代码段在画布上:

DrawingVisual dv = new DrawingVisual(); 
var size = new Size(canvas.Width, canvas.Height); 

using(DrawingContext dc = dv.RenderOpen()) 
{ 
    // draw a transparent rect so the text doesn't stretch (fixes size) 
    dc.DrawRectangle(Brushes.Transparent, null, new Rect(0, 0, size.Width, size.Height)); 

    RadioInterface.DrawDisplay(dc, size); 
} 

canvas.Background = new VisualBrush(dv); 

我能够“修理”这个记忆通过注释掉只有“dc.DrawText(...”这一行。这样做,应用程序的内存使用是完全平坦的。除此之外,我不知道该怎么尝试。我尝试搜索与DrawText相关的内存泄漏但没有找到任何结果,我的函数中使用的代码几乎与实例相同用于DrawText的MSDN网站上。

有没有人看到这个或看到我做错了什么?

  • 我尝试使用CLRProfiler,但我不是很熟悉它和内存泄漏是如此之慢,我无法得到任何有用的信息(可能是缺乏了解该工具)。
+0

我怀疑在dc.DrawText中存在内存泄漏,因为这在应用程序中非常常见,其他可能的其他可能的东西仍然保留在某处的对象引用,并且这阻止了GC收集对象。 –

+0

我不认为是这种情况,因为只有评论该单行删除内存泄漏。事实证明,在3.5sp1中有一个错误,我即将发布有关...的答案。 – bj0

回答

2

因此,一些更多的阅读和重新阅读后,我注意到从这篇博客的评论:。https://blogs.msdn.com/b/jgoldb/archive/2008/02/04/finding-memory-leaks-in-wpf-based-applications.aspx?Redirected=true

“这是在WPF出现在版本泄漏3.5 SP1仅这发生在一个VisualBrush ,WriteableBitmap或一些其他类在Viewport3D中以软件渲染模式使用。“

我使用一个视口,而不是一个Viewport3D,但我使用的是软件渲染,如果我将VisualBrush更改为SolidColorBrush,正如后文中建议的那样测试泄漏,它会消失。另外,从DrawingVisual转换为DrawingGroup也可以修复泄漏。

代码的第二块改变到以下固定的泄漏:

DrawingVisual dg = new DrawingGroup(); 
var size = new Size(canvas.Width, canvas.Height); 

using(DrawingContext dc = dg.Open()) 
{ 
    // draw a transparent rect so the text doesn't stretch (fixes size) 
    dc.DrawRectangle(Brushes.Transparent, null, new Rect(0, 0, size.Width, size.Height)); 

    RadioInterface.DrawDisplay(dc, size); 
} 

canvas.Background = new DrawingBrush(dg); 

我使用DrawingVisual类对象,并且还试图重新使用它遍地,而不是每个I画时间创建一个新的,这也确定了泄漏。

编辑:我使用DrawingVisual的原始原因是它导致与我尝试的替代方案相比,包括DrawingGroup在内的最低cpu使用率。差异不大,但一致。