title: C# WebAPI Garbage Collection
body: <p>I just delivered my first C# WebAPI application to the first customer. Under normal load, performance initially is even better than I expected. Initially.</p>
  
  <p>Everything worked fine until, at some point, memory was up and garbage collection started running riot (as in "It collects objects that are not yet garbage"). At that point, there were multiple W3WP threads with some ten gigs of ram altogether, and single-digit gigs per worker. After a restart of the IIS everything was back to normal, but of course the memory usage is rising again.</p>
  
  <p>Please correct me if I am wrong, but </p>
  
  <ul>
  <li>Shouldn't C# have automatic garbage collection?</li>
  <li>Shouldn't it be easy for GC to collect the garbage of a WebAPI application?</li>
  </ul>
  
  <p>And please help me out:</p>
  
  <ul>
  <li>How can I explicitly state what GC should collect, thus preventing memory leaks? Is <code>someBigList = null;</code> the way to go?</li>
  <li>How can I detect where the memory leaks are?</li>
  </ul>
  
  <p>EDIT: Let me clarify some things.</p>
  
  <p>My .NET WebAPI application is mostly a bunch of</p>
  
  <pre><code>public class MyApiController:ApiController
  {
      [HttpGet]
      public MyObjectClass[] MyApi(string someParam) {
          List&lt;MyObjectClass&gt; list = new List&lt;MyObjectClass&gt;();
          ...
          for/while/foreach {
              MyObjectClass obj = new MyObjectClass();
              obj.firstStringAttribute = xyz;
              ...
              list.Add(obj);
          }
          return list.ToArray();
      }
  }
  </code></pre>
  
  <p>Under such conditions, GC should be easy: after "return", all local variables should be garbage. Yet with every single call the used memory increases.</p>
  
  <p>I initially thought that C# WebAPI programs behave similar to (pre-compiled) PHP: IIS calls the program, it is executed, returns the value and is then completely disposed off.</p>
  
  <p>But this is not the case. For instance, I found static variables to keep their data between runs, and now I disposed of all static variables.</p>
  
  <p>Because I found static variables to be a problem for GC:</p>
  
  <pre><code> internal class Helper
   {
       private static List&lt;string&gt; someVar = new List&lt;string&gt;();
       internal Helper() {
           someVar=new List&lt;string&gt;();
       }
       internal void someFunc(string str) {
           someVar.Add(str);
       }
       internal string[] someOtherFunc(string str) {
           string[] s = someVar.ToArray();
           someVar=new List&lt;string&gt;();
           return s;
       }
   }
  </code></pre>
  
  <p>Here, under low-memory conditions, someVar threw a null pointer error, which in my opinion can only be caused by GC, since I did not find any code where <code>someVar</code> is actively nullified by me.</p>
  
  <p>I think the memory increase slowed down since I actively set the biggest array variables in the most often used Controllers to null, but this is only a gut feeling and not even nearly a complete solution.</p>
  
  <p>I will now do some profiling using the link you provided, and get back with some results.</p>