位图和hBitmap内存泄漏
本文关键字:泄漏 内存 hBitmap 位图 | 更新日期: 2023-09-27 18:12:29
我用WebCam_Capture.dll
从我的网络摄像机捕获图像到WPF中的图像控制。对于每个捕获的帧,我都有一个称为webCam_imageCaptured
的事件。每次当我从网络摄像头接收到新的图像时,它都会调用。在这个事件中,我调用LoadBitmap
方法来获取hBitmap并接收BitmapSource,以将捕获的图片放入图像控件。下面是这个方法的代码:
[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负载高达1gb,有时甚至更多!DeleteObject(ip)
不是每次调用都有效。当RAM为1 GB或更多时,它会释放或显示我内存不足错误。如何解决这个问题?
没有分析器的帮助,甚至没有看到您的代码的其余部分,我几乎可以保证"泄漏"在这里:
_frameImage.Source = LoadBitmap((System.Drawing.Bitmap)e.WebCamImage);
该方法当然是被调用非常快,你不是Dispose()
你的Bitmaps
。GC将没有时间在您之后进行清理并在每个Bitmap
上调用终结器,因此您将耗尽内存。
你需要在完成Bitmap
之后调用Dispose()
。BitmapSource
无论如何都会复制图像数据,因此不应该需要它。我想试试这个:
private void webcam_ImageCaptured(object source, WebcamEventArgs e)
{
using( Bitmap b = e.WebCamImage )
{
_frameImage.Source = LoadBitmap((System.Drawing.Bitmap)e.WebCamImage);
}
}
这当然假设在这个事件处理程序中处理位图是一个有效的事情(即,其他人处理这个事件吗?)您可能希望在WebCamEventArgs
类中公开BitmapSource
,这样您就可以确保没有其他客户端依赖于该Bitmap
保持有效。
当然前提是你编写了API。如果没有,您可以编写一个包装器,以确保您的代码永远不会实际看到Bitmap
,而只处理WPF图像类型。