Collect objects still in the area - GC.Collect

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(); /* * Output: * * Memory: 186836 * Memory: 105044468 * Memory: 104963676 * */ } } 

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?

+4
source share
2 answers

Mentioned in the comments on Raymond's article and in Yun Jin's MSDN article here , which

In fact, for debugged code, JIT extends the life span for each variable to the end of the function.

Therefore, your collection will not be compiled in debug mode, as you have discovered, and why it will be compiled in Release mode.

+6
source

The behavior of the collector is not deterministic, and it cannot be expected that he will be deterministic. Do not rely on the GC.

You ask why the GC is not collecting your garbage at a given time. The best question is why it is a collection at a given time.

0
source

Source: https://habr.com/ru/post/891815/


All Articles