Hi everyone I'm making a C# WinForms application that searches for duplicate images in a directory. It starts by calling a constructor with every image in the directory.
There is a lot of files in the directory and memory was quickly rising to 2gb and then the program would throw an out of memory exception.
Now I've added a check in my for loop to check if the memory has exceeded 800 Megabits and I force a garbage collection. But I've noticed after the first forced collection the memory no longer rises. (The forced garbage collection occurs at loop ~180 out of ~800 then it never occurs again)
(It looks a little like a shark fin swimming through the water leaving waves in its wake.)
I'm stumped as to why this is happening and have come here in search of help.
private void GeneratePrints()
{
for (int i = 0; i < files.Count; i++)
{
if (imageFileExtensions.Contains(Path.GetExtension(files[i])))
prints.Add(new FilePrint(directory + "/" + files[i]));
//800 Megabits
const long MAX_GARBAGE = 800 * 125000;
if (GC.GetTotalMemory(false) > MAX_GARBAGE)
{
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
Console.WriteLine("File Prints Complete.");
}
GeneratePrints() is called 1 time, once a directory is selected.
I will also show you the constructor for the FilePrint class. I'm pretty sure this all has something to do with the MemoryStream object.
public FilePrint(string filename)
{
Bitmap img;
using (var fs = new FileStream(filename, FileMode.Open))
{
using (var ms = new MemoryStream())
{
fs.CopyTo(ms);
ms.Position = 0;
img = (Bitmap)Bitmap.FromStream(ms);
ms.Close();
}
fs.Close();
}
this.size = img.Size;
img = ResizeImage(img, 8, 8);
img = MakeGrayscale(img);
//I do some basic for-loop arithmetic here
//calculating the average color of the image, not worth posting.
img.Dispose();
}
So basically I'm wondering how can I make it so that the 'shark-fin-like' memory usage spike at the start never happens so that I do not have to force a garbage collection.
Here is a memory snapshot I have taken when the forced garbage collection occurs (Am I not disposing of the MemoryStreams properly?):
Thank you for your replies, ideas and answers in advance!