C#Bitmap处理内存使用情况

时间:2016-12-23 00:38:54

标签: c# memory bitmap garbage-collection

我目前正在将网络摄像头功能应用到我正在创建的应用中,但是我在内存使用方面遇到了一些问题。

我的功能如下所示

这是第一个实现

private void webcam_newFrame(object sender, NewFrameEventArgs eventArgs) {
    if (!_pause) {
        var img = (Bitmap) eventArgs.Frame.Clone();
        pbPicture.BackgroundImage = img;            
    }
}

然而,这段代码导致巨大的内存泄漏,运行2gb(ram我假设)。在由于内存不足而崩溃之前。 然后我改变了代码来处理Bitmap,就像这样

private void webcam_newFrame(object sender, NewFrameEventArgs eventArgs) {
    if (!_pause) {
        var img = (Bitmap) eventArgs.Frame.Clone();
        pbPicture.BackgroundImage = img;
        img.Dispose(); // This causes exception
    }
}

这会导致抛出异常:' System.ArgumentException'在System.Drawing.dll中。

附加信息:参数无效。

在以下代码中调用此表单:

WebcamForm wForm = new WebcamForm();
wForm.ShowDialog();

然后我将功能更改为:

private void webcam_newFrame(object sender, NewFrameEventArgs eventArgs) {
    if (!_pause) {
        pbPicture.BackgroundImage = (Bitmap)eventArgs.Frame.Clone();
        GC.Collect();
    }
}

此代码正常工作,内存使用率保持在360mb左右,这是一致的,考虑到应用程序是合理的数字。

我的问题是,在每一帧上强制垃圾收集是一个很好的解决方案吗?有任何潜在的问题吗?

我确信我过去曾经看到强制垃圾收集的答案是一件坏事,但是我无法想到解决这个问题的其他方法。

干杯

2 个答案:

答案 0 :(得分:2)

您需要处理BackgroundImage的旧值,而不是您传入的新值。

private void webcam_newFrame(object sender, NewFrameEventArgs eventArgs) {
    if (!_pause) {
        var img = (Bitmap) eventArgs.Frame.Clone();
        var oldImg =  pbPicture.BackgroundImage;
        pbPicture.BackgroundImage = img;
        oldImg?.Dispose();
    }
}

答案 1 :(得分:1)

经常调用垃圾收集器是一种不好的做法。

尝试在newone之后处理旧位图。

private void webcam_newFrame(object sender, NewFrameEventArgs eventArgs) {
  if (!_pause) {
      Bitmap oldBitmap = (Bitmap)pbPicture.BackgroundImage;
      pbPicture.BackgroundImage = (Bitmap)eventArgs.Frame.Clone();
      oldBitmap.Dispose();
  }
}