gpt4 book ai didi

c# - Aforge 和 Windows 窗体的内存堆叠问题

转载 作者:行者123 更新时间:2023-11-30 17:44:52 25 4
gpt4 key购买 nike

我在我的 c# windows 窗体程序中遇到了一个奇怪的内存堆栈,它在速度较慢的 PC 上一直发生,并且当 windows 窗体失去焦点或在较快的 PC 上被中断时。

我编写的程序使用 Aforge 从我的网络摄像头获取图像,然后我将其显示在 Windows 窗体的 Aforge 图片框控件(代码中为 CurrImagePic)中。图像被切换到图片框中,然后以相机的原始帧速率进行处理,因此它对用户来说显示为视频,而不是静止图像。图片框是 1080x1920,但它在表单中的空间较小,所以我允许用户滚动图片。

在较慢的 PC 上内存稳定运行约 30 秒后,问题开始出现。在速度更快的 PC 上,仅当按住滚动条箭头或单击并拖动任一滚动条时,以及如果我锁定 PC 或调出 Ctrl+Alt+Delete 菜单时,才会出现此问题。

问题本身是程序使用的内存开始以非常大的 block 增加,导致内存不足崩溃。这在较慢的 PC 上是无法停止的,但在较快的 PC 上,如果您停止滚动或从锁定/Ctrl+alt+delete 菜单返回,程序会稳定在较高的内存使用级别。垃圾收集器永远不会收集在滚动期间或在锁定菜单中时产生的内存。我什至尝试放入一个按钮,在按下时强制执行 GC.collect(),但它不会减少内存使用量。

我已经运行 perfmon 并发现内存增加是在非托管堆上,但我不知道它是否来自未被处置的位图或者它可能来自什么。不可能追踪到,因为它不会发生,除非在上述条件下。我尝试了各种解决方案(比如将我的图像处理移出事件处理程序,甚至同时使用全局标志和“锁定”语句来尝试确保只有一个线程或框架可以同时访问图像处理和显示方法,但我没有看到任何变化。事实上,我现在看到一些无法解释的内存使用小跳跃,这是我在放入锁并将处理移出处理程序之前没有看到的。

有人遇到过这种情况吗?我不知道我需要修复什么,而且我没有从 Aforge 论坛获得太多帮助。我认为问题是基于我的 Aforge 事件处理程序和图像处理方法,如果它完全在我的代码中 - 但我也怀疑这是我滥用或不能使用的 Windows 窗体代码中更深层次的东西跟上我的代码的要求。代码如下:

//Applicable Globals to this code snippet
private bool ALLOWFRAME = true;
private Object FRAMEKEY = new Object();
private VideoCaptureDevice COMPVID;
private Bitmap TMPLTCAP;
private System.Drawing.Image OLDIMAGE;
private bool RCRDPIC = false;

private void COMPVID_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
//Only process a frame when another is done processing
if (ALLOWFRAME == true)
{
ALLOWFRAME = false;
Bitmap PassFrame = AForge.Imaging.Image.Clone(eventArgs.Frame);
ProcessFrame(PassFrame);
PassFrame.Dispose();
}
}

private void ProcessFrame(Bitmap frameIn)
{
lock (FRAMEKEY)
{
if (OLDIMAGE != null) { OLDIMAGE.Dispose(); }
//Call comparison method if flag is set.
if (COMPON == true)
{
Difference TmpltFilter = new Difference(TMPLTCAP);
TmpltFilter.ApplyInPlace(frameIn);

OLDIMAGE = CurrImagePic.Image;
CurrImagePic.Image = AForge.Imaging.Image.Clone(frameIn);
OLDIMAGE.Dispose();
}
else
{
OLDIMAGE = CurrImagePic.Image;
CurrImagePic.Image = AForge.Imaging.Image.Clone(frameIn);
OLDIMAGE.Dispose();
//Toggle the flag back to false to show it's safe (i.e., comparisons have stopped)
//for the result-recording method to copy from the picture box if it is attempting to copy
if (RCRDPIC == true)
{
RCRDPIC = false;
}
}
ALLOWFRAME = true;
}
}

最佳答案

一种经常提高性能的方法是在内存中对图像进行排队,并使用计时器控件将它们出列/显示在图片框中。通过这种方式,您可以控制适当的处置并允许 NewFrame 事件更快地返回,而不是被图像处理所束缚。

此外,在 Timer_Tick 事件中,尝试执行以下操作:

this.Timer.Stop();
Bitmap image = null;
var temp = this.PictureBox.Image;

lock (FRAMEKEY)
{
if (this.ImageQueue.Any())
{
image = this.ImageQueue.Dequeue();
if (temp != null) { temp.Dispose(); }
}
}

this.PictureBox.Image = image;
if (temp != null) { temp.Dispose(); }

this.Timer.Start();

关于c# - Aforge 和 Windows 窗体的内存堆叠问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28861178/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com