使用RenderTargetBitmap的WPF内存泄漏?

时间:2013-02-09 09:00:18

标签: wpf memory-leaks rendertargetbitmap

我对WPF代码中的内存泄漏感到有些困惑。我将一些3D几何体渲染到几个RenderTargetBitmaps,然后将每个3D几何体渲染为一个大的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);
   }   

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

1 个答案:

答案 0 :(得分: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);
}