【问题标题】:C# Canon EDSDK Memory leak during Live ViewC# Canon EDSDK 在实时查看期间内存泄漏
【发布时间】:2019-09-05 11:12:46
【问题描述】:

我正在使用 Canon EDSDK 库开发小型 c# wpf 应用程序。我正在使用实时查看功能,在我的桌面应用程序中显示来自佳能相机的实时图片。

在实时取景过程中(while 循环),应用程序在内存中增长。我知道它应该增长,一段时间后 GC 运行并清除内存。但即使 GC 清除内存后,它也永远不会回到起始级别。

另外,经过长时间的工作,我的应用关闭的时间非常长 - 有时甚至需要几分钟才能完全关闭。

我期待,我有内存泄漏,但我看不到它在哪里。

这是我使用主 while 循环的实时查看方法:

private uint DownloadEvfData(MainWindow MW)
            {
                uint err = EDSDK.EDS_ERR_OK;
                IntPtr stream = new IntPtr();
                IntPtr evfImage = new IntPtr();
                BitmapImage bmp = new BitmapImage();
                var transform = new ScaleTransform(-1, 1, 0, 0);

            while (isLVRunning)
            {
                // Create an Eds Memory Stream
                err = EDSDK.EdsCreateMemoryStream(0, out stream);

                // Create an Eds EVF Image ref
                if (err == EDSDK.EDS_ERR_OK)
                {
                    err = EDSDK.EdsCreateEvfImageRef(stream, out evfImage);
                }

                // Download the EVF image
                if (err == EDSDK.EDS_ERR_OK)
                    err = EDSDK.EdsDownloadEvfImage(cameraDev,
                    evfImage);

                bmp = GetEvfImage(stream);

                // do something with the bitmap
                if (bmp != null)
                {
                    // I need to show mirror flipped image

                    var mirror_bmp = new TransformedBitmap();
                    mirror_bmp.BeginInit();
                    mirror_bmp.Source = bmp;
                    mirror_bmp.Transform = transform;
                    mirror_bmp.EndInit();

                    mirror_bmp.Freeze();

                    MW.image1.Source = null;
                    MW.image1.Source = mirror_bmp;

                    RefreshScreen();

                    bmp = null;
                    mirror_bmp = null;
                }


                // Release the Evf Image ref
                if (evfImage != null)
                {
                    err = EDSDK.EdsRelease(stream);
                    evfImage = IntPtr.Zero;
                }

                // Release the stream
                if (stream != null)
                {
                    err = EDSDK.EdsRelease(stream);
                    stream = IntPtr.Zero;
                }
            }
            transform = null;
            return err;
        }

返回单个BitmapImage(单帧)进行实时取景的方法如下:

public unsafe static BitmapImage GetEvfImage(IntPtr evfStream)
        {
            IntPtr jpgPointer;
            uint err;
            uint length = 0;
            BitmapImage i = null;

            err = EDSDK.EdsGetPointer(evfStream, out jpgPointer);

            if (err == EDSDK.EDS_ERR_OK)
                err = EDSDK.EdsGetLength(evfStream, out length);

            if (err == EDSDK.EDS_ERR_OK)
            {
                if (length != 0)
                {
                    using (UnmanagedMemoryStream ums = new UnmanagedMemoryStream
                    ((byte*)jpgPointer.ToPointer(), length, length, FileAccess.Read))
                    {
                        i = new BitmapImage();
                        i.BeginInit();
                        i.CacheOption = BitmapCacheOption.OnLoad;
                        i.StreamSource = ums;
                        i.EndInit();
                        i.Freeze();
                    }
                }
            }
            return i;
        }

我做错了什么?你能帮我追踪泄漏或告诉我我的问题在哪里吗?我试图在将位图用作图像源之前冻结它们,但应用程序仍在泄漏。

我将非常感谢您的所有建议。

谢谢

谢谢 达里奥

【问题讨论】:

    标签: c# memory-leaks edsdk canon-sdk


    【解决方案1】:
     // Release the Evf Image ref
     if (evfImage != null)
     {
         err = EDSDK.EdsRelease(stream); // this should release the evfImage
         evfImage = IntPtr.Zero;
     }
    

    可能只是一个错字,但您释放了两次流并且从未释放 evfImage。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-11
      • 1970-01-01
      • 2013-09-15
      • 1970-01-01
      • 1970-01-01
      • 2016-07-04
      • 2016-01-27
      • 2010-11-11
      相关资源
      最近更新 更多