我目前正在将网络摄像头功能应用到我正在创建的应用中,但是我在内存使用方面遇到了一些问题。
我的功能如下所示
这是第一个实现
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左右,这是一致的,考虑到应用程序是合理的数字。
我的问题是,在每一帧上强制垃圾收集是一个很好的解决方案吗?有任何潜在的问题吗?
我确信我过去曾经看到强制垃圾收集的答案是一件坏事,但是我无法想到解决这个问题的其他方法。
干杯
答案 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();
}
}