I am experiencing a strange memory stack-up in my c# windows form program that occurs all the time on slow PCs, and when the windows form loses focus or is otherwise interrupted on faster PCs.
The program I have written uses Aforge to get images from my webcam, which I then display in an Aforge picturebox control (CurrImagePic in code) in the windows form. The images are switched into the picture box and then disposed at the camera's native framerate, so it appears as video to the user, not still images. The picture box is 1080x1920, but the space for it in the form is smaller and so I allow the user to scroll around the picture.
After about ~30 seconds of memory-stable operation on slower PCs, the problem begins. On faster PCs, the problem only occurs when holding down scroll bar arrows or clicking and dragging around either scroll bar, and if I lock the PC or bring up the Ctrl+Alt+Delete menu.
The problem itself is that memory used by the program starts to increase in very large chunks, leading to an out of memory crash. This is unstoppable on slower PCs, but on the faster PCs if you stop scrolling or return from the lock/Ctrl+alt+delete menu, the program stabilizes at the higher memory usage level. The memory that was accrued during scrolling or while in the lock menu is never collected by the garbage collector. I've even tried to put in a button that forces a GC.collect() when pressed, and it does not reduce this memory usage.
I've run perfmon and found that the memory increase is on the unmanaged heap, but I don't know if it's coming from bitmaps which are not being disposed or what it could be from. It's been impossible to track down since it does not occur except in the above conditions. I've tried various solutions (like moving my image processing out of the event handler and even using both global flags and a "lock" statement to try and ensure that only one thread or frame can access the image processing and displaying method at at time, but I have seen no change. In fact, I am now seeing some unexplained small jumps in memory usage that I wasn't seeing before I put in the lock and moved the processing out of the handler.
Has anyone run into situations like this? I am at a loss for what I need to fix, and I am not getting much help from the Aforge forums. I think the problem is based around my Aforge event handler and image processing method if it is in my code at all - but I also have a suspicion that this is something deeper in the windows form code that I am either misusing or that can't keep up with the demands of my code. Code below:
//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;
}
}