4

WPFコードのメモリリークに少し困惑しています。いくつかの3DジオメトリをいくつかのRenderTargetBitmapにレンダリングしてから、それぞれを大きなマスターRenderTargetBitmapにレンダリングしています。しかし、これを行うと、メモリリークが発生し、わずか1〜2分後にアプリがクラッシュします。

次の簡略化されたコードでエラーを再現しました。

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

誰かがここでうまくいかない明らかな何かを見ることができますか?このコードでひどいメモリリークが発生するのはなぜですか?

4

1 に答える 1

1

Resource MonitorRenderTargetBitmapを使用してクラスの動作を監視すると、このクラスが呼び出されるたびに 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);
}   
于 2014-07-21T20:36:00.497 に答える