【问题标题】:WPF Memory Leak using RenderTargetBitmap?使用 RenderTargetBitmap 的 WPF 内存泄漏?
【发布时间】:2013-01-25 00:58:27
【问题描述】:

我对 WPF 代码中的内存泄漏感到有些困惑。我将一些 3D 几何图形渲染到几个 RenderTargetBitmap,然后将每个渲染到一个大型的主 RenderTargetBitmap。但是当我这样做时,我得到一个内存泄漏,使我的应用程序在一两分钟后崩溃。

我在下面的简化代码中重现了错误。

   private void timer1_Tick(object sender, EventArgs e) {
       // if first time, create final stitch bitmap and set UI image source
       if (stitch == null) {
           stitch = new RenderTargetBitmap(1280, 480, 96, 96, PixelFormats.Pbgra32);
           myImage.Source = stitch;
       }

       // create visual and render to img1
       Rect rect = new Rect(new Point(160, 100), new Size(320, 80));
       DrawingVisual dvis = new DrawingVisual();
       using (DrawingContext dc = dvis.RenderOpen()) {
           dc.DrawRectangle(System.Windows.Media.Brushes.LightBlue, (System.Windows.Media.Pen)null, rect); 
       }
       RenderTargetBitmap img1 = new RenderTargetBitmap(640, 480, 96, 96, PixelFormats.Pbgra32);
       img1.Render(dvis);

       // create visual and render to final stitch
       DrawingVisual vis = new DrawingVisual();
       using (DrawingContext dc = vis.RenderOpen()) {
           dc.DrawImage(img1, new Rect(0, 0, 640, 480));
       }

       stitch.Clear();
       stitch.Render(vis);
   }   

任何人都可以看到这里有什么明显的问题吗?为什么这段代码会有严重的内存泄漏?

【问题讨论】:

  • 我想我也看到了这个。你得到什么例外?

标签: wpf memory-leaks rendertargetbitmap


【解决方案1】:

如果您使用 Resource Monitor 监控 RenderTargetBitmap 类的行为,您可以看到每次调用该类时,您会损失 500KB 的内存。我对您的问题的回答是:不要多次使用RenderTargetBitmap

你甚至不能释放 RenderTargetBitmap 的已用内存。

如果您确实需要使用 RenderTargetBitmap 类,只需在代码末尾添加这些行。

GC.Collect()
GC.WaitForPendingFinalizers()
GC.Collect()

这也许能解决你的问题:

private void timer1_Tick(object sender, EventArgs e) {
       // if first time, create final stitch bitmap and set UI image source
       if (stitch == null) {
           stitch = new RenderTargetBitmap(1280, 480, 96, 96, PixelFormats.Pbgra32);
           myImage.Source = stitch;
       }

       // create visual and render to img1
       Rect rect = new Rect(new Point(160, 100), new Size(320, 80));
       DrawingVisual dvis = new DrawingVisual();
       using (DrawingContext dc = dvis.RenderOpen()) {
           dc.DrawRectangle(System.Windows.Media.Brushes.LightBlue, (System.Windows.Media.Pen)null, rect); 
       }
       RenderTargetBitmap img1 = new RenderTargetBitmap(640, 480, 96, 96, PixelFormats.Pbgra32);
       img1.Render(dvis);

       // create visual and render to final stitch
       DrawingVisual vis = new DrawingVisual();
       using (DrawingContext dc = vis.RenderOpen()) {
           dc.DrawImage(img1, new Rect(0, 0, 640, 480));
       }

        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();
       stitch.Clear();
       stitch.Render(vis);
}   

【讨论】:

  • 哇。来回这里的一次旅行。我们早已完全脱离 WPF,因此解决方案不再紧迫。但感谢您抽出宝贵时间回复。我已将您的答案标记为已接受。我想另一种解决方案是重复保留和重复使用相同的 RenderTargetBitmaps。现在似乎有点明显了。很高兴知道他们没有很好地清理自己。所以,感谢您抽出宝贵时间回复。
猜你喜欢
  • 2011-10-06
  • 2017-10-14
  • 2011-02-21
  • 1970-01-01
  • 2010-12-05
  • 2011-03-19
相关资源
最近更新 更多