In my job we had a problem with OutOfMemoryExpections. I've written simple piece of code to mimic some behavior, and I've ended up with the following mystery. Look at this simple code which blows up when it runs out of memory.
class Program
{
private static void Main()
{
List<byte[]> list = new List<byte[]>(200000);
int iter = 0;
try
{
for (;;iter++)
{
list.Add(new byte[10000]);
}
}
catch (OutOfMemoryException)
{
Console.WriteLine("Iterations: " + iter);
}
}
}
On my machine it ended up with
Iterations: 148008
Then I added GC.Collect
call to the loop after each thousand iterations:
//...
for (;;iter++)
{
list.Add(new byte[10000]);
if (iter % 1000 == 0)
GC.Collect();
}
//...
And surprise:
Iterations: 172048
When I called GC.Collect
after each 10 iterations, I even got 193716 cycles. There are two strange things:
1) How manual call to GC.Collect
can have such a severe impact (up to 30% more allocated)?
2) What the hell can GC collect, when there're no "lost" references (I've even preset the List's capacity)?