c# - 位图和 hBitmap 内存泄漏

标签 c# .net wpf memory-leaks

我使用 WebCam_Capture.dll 从我的网络摄像头捕获图像到 WPF 中的图像控件。对于每个捕获的帧,我都有名为 webCam_imageCaptured 的事件。每当我从网络摄像头收到新图像时,它都会调用。在此事件中,我调用方法 LoadBitmap 获取 hBitmap 并接收 BitmapSource 以将捕获的图片放入 Image 控件。 下面是这个方法的代码:

[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr handle);
public BitmapSource bs;
public IntPtr ip;
public BitmapSource LoadBitmap(System.Drawing.Bitmap source)
{
   ip = source.GetHbitmap();
   bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(ip, IntPtr.Zero, System.Windows.Int32Rect.Empty,
   System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
   DeleteObject(ip);
   return bs;
}

这是事件的代码:

private void webcam_ImageCaptured(object source, WebcamEventArgs e)
{
    //_frameImage is Image WPF control.
     _frameImage.Source = LoadBitmap((System.Drawing.Bitmap)e.WebCamImage);   
}

我这里漏水了! RAM 加载高达 1 GB,有时甚至更多! DeleteObject(ip) 并非每次调用时都有效。当 RAM 为 1 GB 或更多时,它会释放或显示内存不足错误。如何解决?

最佳答案

没有分析器的帮助,甚至没有看到你的其余代码,我几乎可以保证“泄漏”就在这里:

_frameImage.Source = LoadBitmap((System.Drawing.Bitmap)e.WebCamImage);

肯定会很快调用该方法,而您不是Dispose()你的 Bitmaps . GC 将没有时间在您之后进行清理并在每个 Bitmap 上调用终结器。 , 所以内存不足。

您需要调用Dispose()在那Bitmap完成后。 BitmapSource无论如何都会制作图像数据的副本,因此不需要它。我会试试这个:

private void webcam_ImageCaptured(object source, WebcamEventArgs e)
{
    using( Bitmap b = e.WebCamImage )
    {
         _frameImage.Source = LoadBitmap((System.Drawing.Bitmap)e.WebCamImage);   
    }
}

这当然假设在这个事件处理程序中处理位图是一件有效的事情(即,是否有其他人处理这个事件?)你可能想公开一个 BitmapSourceWebCamEventArgs类,这样你就可以确保没有其他客户端依赖于 Bitmap保持有效。

当然,前提是您编写了 API 以供使用。如果不是,您可以编写一个包装器以确保您的代码永远不会真正看到 Bitmap。并且只处理 WPF 图像类型。

关于c# - 位图和 hBitmap 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7880763/

相关文章:

c# - 将图像添加到 ListView 中的第一项?

c# - DistanceTransform 在 OpenCVSharp 中不起作用吗?

c# - .NET 中的 OpenCalais 解析 RDF

c# - MVVM DDD 应用程序中的组合根

c# - 在 visual studio 中一次编辑多个资源文件键

.net - 合并 .net 对象图

c# - 通过我的应用程序使用谷歌翻译

c# - 带有异步 lambda 和 Task.WaitAll 的 Task.Factory.StartNew

WPF 更改鼠标悬停和按下的按钮样式

c# - wpf如何自动聚焦于文本框