Note that there are some explanatory texts on larger screens.

plurals
  1. POCould someone explain the behaviour of the garbage collector?
    primarykey
    data
    text
    <p>I am playing around with the garbage collector in C# (or rather the CLR?) trying to better understand memory management in C#.</p> <p>I made a small sample program that reads three larger files into a <code>byte[]</code> buffer. I wanted to see, if </p> <ul> <li>I actually need to to anything in order to handle memory efficient</li> <li>it has any impact when setting the <code>byte[]</code> to null after the end of the current iteration </li> <li>and finally if it would help when forcing a garbage collection via <code>GC.Collect()</code></li> </ul> <p>Disclaimer: I measured memory consumption with windows task manager and rounded it. I tried several times, but overall it remained about the same.</p> <p>Here is my simple sample program:</p> <pre><code>static void Main(string[] args) { Loop(); } private static void Loop() { var list = new List&lt;string&gt; { @"C:\Users\Public\Music\Sample Music\Amanda.wma", // Size: 4.75 MB @"C:\Users\Public\Music\Sample Music\Despertar.wma", // Size: 5.92 MB @"C:\Users\Public\Music\Sample Music\Distance.wma", // Size: 6.31 MB }; Console.WriteLine("before loop"); Console.ReadLine(); foreach (string pathname in list) { // ... code here ... Console.WriteLine("in loop"); Console.ReadLine(); } Console.WriteLine(GC.CollectionCount(1)); Console.WriteLine("end loop"); Console.ReadLine(); } </code></pre> <p>For each test, I only changed the contents of the <code>foreach</code> loop. Then I ran the program, at each <code>Console.ReadLine()</code> I stopped and checked the memory usage of the process in windows task manager. I took notes of the used memory and then continued the program with return (I know about breakpoints ;) ). Just after the end of the loop, I wrote <code>GC.CollectionCount(1)</code> to the console in order to see how often the GC jumped in if at all.</p> <p><br /></p> <h2>Results</h2> <p><hr /> <strong>Test 1:</strong></p> <pre><code>foreach ( ... ) { byte[] buffer = File.ReadAllBytes(pathname); Console.WriteLine ... } </code></pre> <p>Result (memory used):</p> <pre><code>before loop: 9.000 K 1. iteration: 13.000 K 2. iteration: 19.000 K 3. iteration: 25.000 K after loop: 25.000 K GC.CollectionCount(1): 2 </code></pre> <hr /> <p><strong>Test 2:</strong></p> <pre><code>foreach ( ... ) { byte[] buffer = File.ReadAllBytes(pathname); buffer = null; Console.WriteLine ... } </code></pre> <p>Result (memory used):</p> <pre><code>before loop: 9.000 K 1. iteration: 13.000 K 2. iteration: 14.000 K 3. iteration: 15.000 K after loop: 15.000 K GC.CollectionCount(1): 2 </code></pre> <hr /> <p><strong>Test 3:</strong></p> <pre><code>foreach ( ... ) { byte[] buffer = File.ReadAllBytes(pathname); buffer = null; GC.Collect(); Console.WriteLine ... } </code></pre> <p>Result (memory used):</p> <pre><code>before loop: 9.000 K 1. iteration: 8.500 K 2. iteration: 8.600 K 3. iteration: 8.600 K after loop: 8.600 K GC.CollectionCount(1): 3 </code></pre> <hr /> <p><br /></p> <h2>What I dont understand:</h2> <ul> <li>In Test 1, the memory increases with each iteration. Therefore I guess that the memory is NOT freed at the end of the loop. But the GC still says it collected 2 times (<code>GC.CollectionCount</code>). How so?</li> <li>In Test 2, it obviously helps that <code>buffer</code> is set to <code>null</code>. The memory is lower then in Test 2. But why does <code>GC.CollectionCount</code> output 2 and not 3? <em>And why is the memory usage not as low as in Test 3?</em></li> <li>Test 3 uses the least memory. I would say it is so because 1. the reference to the memory is removed (<code>buffer</code> is set to <code>null</code>) and therefore when the garbage collector is called via <code>GC.Collect()</code> it can free the memory. Seems pretty clear.</li> </ul> <p>If anyone with more experience could shed some light on some of the points above, it would really help me. Pretty interesting topic imho.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload