title: C# .NET memory leak: sawtooth memory usage when GC stage#1 and stage#2 run
body: <p>I have an event driven app that I was tasked with maintaining.
  About 100 events run every 30 seconds, on separate timers. Over time the events alias into a constant stream of about 1-3 events per second.
  Memory usage does not appear dependent on the number of events firing in any given second.
  Each event polls data from a Webservice, checks the data using a LINQ2SQL DataContext against the previously polled data (I do not dispose or null out the DataContext when done), and if the data is different, updates the database and pushes the new data as an XML message to receiver service via TCP.</p>
  
  <p>This app appears to have a memory leak which </p>
  
  <ol>
  <li>only manifests after 30m+ of running (either debug or release)</li>
  <li>won't manifest when profiling [I'm using .NET Memory Profiler 4.5]</li>
  </ol>
  
  <p>Characteristics: 
  On startup the program uses ~30MB. As time progresses this Memory usage in Task Manager will begin pogoing, first only slightly, between 50 and 150MB, and eventually gets worse, oscillating between 200MB and 1GB+. When this happens, it happens a few times within a second or two, then settles down at ~150MB for the next 10-20 or so seconds. </p>
  
  <p>I've been trying to catch this behavior in action using memory profiling. So far I've been unsuccessful, I can't get the app to pogo or oscillate in memory usage anywhere near like I can when the profiler isn't watching.
  However, I've been noticing a square-wave sort of pattern on the memory usage as the Garbage Collector stages 1 and 2 run that looks very similar to what I see in Task Manager, except the memory usage oscillations in the square-wave are 10MB wide, instead of 800MB+ (200MB to 1GB+). Now, according to Google Images, Garbage collection in a properly functioning app looks more like a sawtooth wave than square.</p>
  
  <p>I frankly don't see any way that my app could be pogoing between 200MB and 1GB+ of memory usage within a second and NOT be spiking the CPU to 100%.</p>
  
  <p>I have read about some problems that can manifest between garbage collection + event handling, but I have several paths I could go investigate and am trying to narrow down which one to spend time on. I'm still pretty slow at .NET and haven't developed the "intuition" I have for embedded devices running C that generally helps me filter what I should investigate first.
  What if FEELS like is perhaps some event handlers are losing and re-gaining references to [massive amounts of data] (I don't know how this could even happen?) seeing as memory usage appears to spike back up to 1GB soon after the garbage collector runs and drops memory usage back to 200MB.</p>
  
  <p>Previous versions of this app did not have these problems. Two changes I have made since then include</p>
  
  <ol>
  <li>utilizing LINQ2SQL instead of our own data manager (which had an ADORecordSetHelper object we utilized to execute hardcoded SQL statements)</li>
  <li>changing the piece of software we use to send the TCP XML messages to a receiver.
  Due to the simplicity of the what we're doing in #2, it COULD be the source of the problem but this memory usage behavior makes me think otherwise.</li>
  </ol>
  
  <p>I guess my main questions at this point are</p>
  
  <ul>
  <li>Should I be calling dispose on my LINQ2SQL DataContexts before I return from the method I create them in?</li>
  <li>Should I null them out instead?</li>
  <li>if an exception were occuring somewhere in a method after creation of a DataContext, could it cause the DataContext to be kept in memory indefinitely?</li>
  <li>if I store a result from a LINQ query to a value-type (ie int not var), is it lazy-loaded then, or lazy'd when the variable is used?</li>
  <li>how possible is it for event-driven frameworks to hypothetically lose and regain references?</li>
  </ul>
  
  <p>edit: the events have instance-based subscriptions like discussed <a href="https://stackoverflow.com/questions/298261/do-event-handlers-stop-garbage-collection-from-occuring">here</a> and are never unsubscribed for the life of the app.</p>
  
  <p>edit2: finally managed to catch it in the profiler, appears to be a 200MB system.string that's being created somehow. Thanks everyone for ruling out GC behavior.</p>