当我尝试新建一个位图并通过“get”访问器返回它时,我遇到了内存不足异常。位图大小为 640x480,深度为 Int32。
我怀疑 C# 垃圾收集器无法删除这些旧位图,因为它们在访问器中返回到我的变量。我有超过 2GB 的可用空间,所以我不会想象这个“小”图像会占用太多内存。不幸的是,由于线程锁定问题,我不得不更新位图(在线程之间锁定图像时遇到问题)代码如下:
public Bitmap LiveFrame { get { return GetFrame(500); } }
......
private Bitmap GetFrame(int timeout)
{
Bitmap ret = null;
//CLEyeCameraGetFrame places image data into this._PrivateBitmap
bool success = CLEyeCameraGetFrame(_Camera, _PtrBmpPixels, timeout);
if(success)
ret = new Bitmap(this._PrivateBitmap);
return ret;
}
关于非托管代码的注意事项:CLEyeCameraGetFrame 位于非托管 DLL 中。我在代码前面使用 Marshal.AllocHGlobal 分配 _PtrBmpPixels 并且在关闭应用程序时释放之前不要触摸它。_PtrBmpPixels 通过其接受 IntPtr 参数“scan0”的构造函数用于创建位图 _PrivateBitmap。因此,每当通过 CLEyeCameraGetFrame 更新 _PtrBmpPixels 时,也会更新 _PrivateBitmap。
我试图通过在重用之前处理 PcitureBox 位图来解决这个问题,但这破坏了 PictureBox 的显示。我有两个线程更新两个不同的图片框/图像框:
lock (_CameraLocker)
{
if (_VideoPlaying)
{
try{
if (pbLiveFeed.Image != null)
pbLiveFeed.Image.Dispose();
pbLiveFeed.Image = _Camera.LiveFrame;
pbLiveFeed.Invalidate();
}catch (Exception ex) { }
}
……
lock (_CameraLocker)
{
try{
if (ibProcessed.Image != null)
ibProcessed.Image.Dispose();
procImage = new Image<Bgra, Int32>(_Camera.LiveFrame);
procImage.Draw(new Rectangle(10, 20, 20, 15), new Bgra(1.0, 1.0, 1.0, 1.0), 5);
ibProcessed.Image = procImage;
}catch (Exception ex) { }
}
垃圾收集会是造成这种情况的原因吗?从 get 访问器返回新对象是否不安全?