2013-02-09 58 views
4

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

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

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); 
    } 

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

+0

我觉得我看到这一点。你会得到什么例外? – Gleno 2013-04-04 19:29:39

回答

1

如果你监视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); 
} 
+0

哇。在这里回来的路上。我们早已远离WPF,所以解决方案不再紧迫。但感谢您花时间回复。我已经接受了你的答案。我猜想另一个解决方案将是保持和重复使用相同的RenderTargetBitmaps。似乎现在看起来很明显。很高兴知道他们不会自己清理干净。所以,感谢您花时间回复。 – TrespassersW 2014-07-23 16:39:56

+0

@TrespassersW不客气 – GiGatR00n 2014-07-24 12:34:40