2013-02-09 91 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