I read this article: http://blogs.msdn.com/b/oldnewthing/archive/2010/08/10/10048149.aspx and, frankly, I donβt understand every detail. As far as I understand in the code below, c should be compiled even if I don't set c to null. Another thing is that the distributions that occur during foreach, apparently, are not released, while we are within the same function. (See example below)
class Program { public class SomeClass { public byte[] X; public SomeClass() { X = new byte[1024 * 1024 * 100]; X[155] = 10; } } static void Main() { Console.WriteLine("Memory: " + GC.GetTotalMemory(false)); SomeClass c; c = new SomeClass(); Console.WriteLine("Memory: " + GC.GetTotalMemory(false)); GC.Collect(); Console.WriteLine("Memory: " + GC.GetTotalMemory(true)); Console.ReadKey(); } }
EDIT Solution for the first example: Debug mode (does not work in the debugger, but even in compilation mode). If I use Release, it will work as expected: c is compiled even without a null value. The second example applies the same thing.
Second example
static void Main(string[] args) { Console.WriteLine("Startup Memory: " + GC.GetTotalMemory(false)); var obj = BOObject.Get(); Console.WriteLine("Fetched Object: " + GC.GetTotalMemory(false)); GC.Collect(); Console.WriteLine("Fetched Object (Collected): " + GC.GetTotalMemory(false)); foreach (var node in obj.Traverse()) { string name = node.Name; } Console.WriteLine("Traversed: " + GC.GetTotalMemory(false)); GC.Collect(); Console.WriteLine("Traversed (collected): " + GC.GetTotalMemory(false)); obj = null; GC.Collect(); Console.WriteLine("collected: " + GC.GetTotalMemory(true)); Console.Read(); }
Exit:
Boot memory: 193060 Received: 8972464 Received (collected): 5594308 Passed through: 272553096 Passed (received): 269564660 collected: 269564048
If I put the foreach loop in another function and called this function, then the memory used after calling .Collect is about 5800000. So why is garbage not collected when I have a foreach loop in the same function?
source share