title: Possible memory leak with SignalR and/or ConcurrentDictionary or SignalR.InMemoryMessage?
body: <p>There was an issue with SignalR (=&lt; v0.5.1) where requests were hanging around and soaking up memory.  That seems to have been corrected with v0.5.2.  However, there may be an additional issue.</p>
  
  <p>Using <a href="http://msdn.microsoft.com/en-us/windows/hardware/gg463009.aspx" rel="nofollow">WINDBG</a>, I created a memory dump of my newsfeed process.  </p>
  
  <p>First off, here is the count and memory consumption for the SignalR.InMemoryMessage:</p>
  
  <pre><code>133099      6388752 System.Collections.Concurrent.ConcurrentDictionary`2+Node[[System.String, mscorlib],[SignalR.Infrastructure.LockedList`1[[System.Action`1[[System.Collections.Generic.IList`1[[SignalR.InMemoryMessage...
  </code></pre>
  
  <p>Lastly, here are the values for the top 3 memory consuming objects:</p>
  
  <pre><code>000007fef9960bb0    79307    140001536 System.Byte[]
  000007fef9956960  1704571    175128912 System.String
  000007fef995ae68  1901299    549202440 System.Object[]
  </code></pre>
  
  <p>Performing <code>!dumpheap -mt 000007fef995ae68</code>, I get a fairly long rundown of the method table.  Most of the objects are of a relatively small size, which is expected.  However, at the end of the dump, I see the following:</p>
  
  <pre><code>00000001eb0f3220 000007fef995ae68      160     
  00000001eb0f3580 000007fef995ae68       40     
  00000001eb0f35f0 000007fef995ae68       40     
  00000001eb0f3758 000007fef995ae68       56     
  00000001eb0f37c8 000007fef995ae68       88     
  00000001eb0f3820 000007fef995ae68       48     
  00000001eb0f3cc8 000007fef995ae68       40     
  00000001eb0f4570 000007fef995ae68       40     
  00000001eb0f45e0 000007fef995ae68       40     
  00000001eb0f4650 000007fef995ae68       40     
  00000001eb0f4de8 000007fef995ae68      176     
  00000001eb0f4ed0 000007fef995ae68       40     
  00000001eb9b3380 000007fef995ae68       40     
  00000001eb9b33c0 000007fef995ae68       40     
  0000000237580080 000007fef995ae68  1146888 
  </code></pre>
  
  <p>So I go ahead and do <code>!gcroot 0000000237580080</code>.  Some of the initial dumps are as follows:</p>
  
  <pre><code>0000000237580080 000007fef995ae68  1146888     
  total 0 objects
  ------------------------------
  total 0 objects
  Statistics:
                MT    Count    TotalSize Class Name
  000007fef995ae68  1901299    549202440 System.Object[]
  Total 1901299 objects
  0:045&gt; !gcroot 0000000237580080 
  Note: Roots found on stacks may be false positives. Run "!help gcroot" for
  more info.
  Scan Thread 11 OSTHread 1040
  Scan Thread 24 OSTHread c18
  Scan Thread 26 OSTHread 488
  Scan Thread 27 OSTHread 1144
  Scan Thread 28 OSTHread 14b0
  RSP:57ae0f0:Root:  000000012acea438(MyApp.Newsfeed.Hubs.NewsfeedHub)-&gt;
    000000012acea5f8(SignalR.GroupManager)-&gt;
    0000000185a17328(SignalR.Connection)-&gt;
    000000011f655ed0(SignalR.InProcessMessageBus)-&gt;
    000000011f656680(System.Collections.Concurrent.ConcurrentDictionary`2[[System.String, mscorlib],[SignalR.Infrastructure.LockedList`1[[System.Action`1[[System.Collections.Generic.IList`1[[SignalR.InMemoryMessage`1[[System.UInt64, mscorlib]], SignalR]], mscorlib]], mscorlib]], SignalR]])-&gt;
    0000000237580080(System.Object[])
  RSP:57ae100:Root:  000000012acea098(System.Linq.Enumerable+WhereSelectEnumerableIterator`2[[SignalR.Hubs.IDisconnect, SignalR],[System.Threading.Tasks.Task, mscorlib]])-&gt;
    000000012acea058(System.Func`2[[SignalR.Hubs.IDisconnect, SignalR],[System.Threading.Tasks.Task, mscorlib]])-&gt;
    000000012ace9ea8(SignalR.Hubs.HubDispatcher+&lt;&gt;c__DisplayClass1a`1[[SignalR.Hubs.IDisconnect, SignalR]])-&gt;
    0000000185a13640(SignalR.Hubs.HubDispatcher)-&gt;
    000000011f655ed0(SignalR.InProcessMessageBus)-&gt;
    000000011f656680(System.Collections.Concurrent.ConcurrentDictionary`2[[System.String, mscorlib],[SignalR.Infrastructure.LockedList`1[[System.Action`1[[System.Collections.Generic.IList`1[[SignalR.InMemoryMessage`1[[System.UInt64, mscorlib]], SignalR]], mscorlib]], mscorlib]], SignalR]])-&gt;
    0000000237580080(System.Object[])
  RSP:57ae130:Root:  000000012acea438(MyApp.Newsfeed.Hubs.NewsfeedHub)-&gt;
    000000012acea5f8(SignalR.GroupManager)-&gt;
    0000000185a17328(SignalR.Connection)-&gt;
    000000011f655ed0(SignalR.InProcessMessageBus)-&gt;
    000000011f656680(System.Collections.Concurrent.ConcurrentDictionary`2[[System.String, mscorlib],[SignalR.Infrastructure.LockedList`1[[System.Action`1[[System.Collections.Generic.IList`1[[SignalR.InMemoryMessage`1[[System.UInt64, mscorlib]], SignalR]], mscorlib]], mscorlib]], SignalR]])-&gt;
    0000000237580080(System.Object[])
  RSP:57ae140:Root:  000000012acea438(MyApp.Newsfeed.Hubs.NewsfeedHub)-&gt;
    000000012acea5f8(SignalR.GroupManager)-&gt;
    0000000185a17328(SignalR.Connection)-&gt;
    000000011f655ed0(SignalR.InProcessMessageBus)-&gt;
    000000011f656680(System.Collections.Concurrent.ConcurrentDictionary`2[[System.String, mscorlib],[SignalR.Infrastructure.LockedList`1[[System.Action`1[[System.Collections.Generic.IList`1[[SignalR.InMemoryMessage`1[[System.UInt64, mscorlib]], SignalR]], mscorlib]], mscorlib]], SignalR]])-&gt;
    0000000237580080(System.Object[])
  RSP:57ae188:Root:  000000012ace9ea8(SignalR.Hubs.HubDispatcher+&lt;&gt;c__DisplayClass1a`1[[SignalR.Hubs.IDisconnect, SignalR]])-&gt;
    0000000185a13640(SignalR.Hubs.HubDispatcher)-&gt;
    000000011f655ed0(SignalR.InProcessMessageBus)-&gt;
    000000011f656680(System.Collections.Concurrent.ConcurrentDictionary`2[[System.String, mscorlib],[SignalR.Infrastructure.LockedList`1[[System.Action`1[[System.Collections.Generic.IList`1[[SignalR.InMemoryMessage`1[[System.UInt64, mscorlib]], SignalR]], mscorlib]], mscorlib]], SignalR]])-&gt;
    0000000237580080(System.Object[])
  RSP:57ae190:Root:  000000012ace9ea8(SignalR.Hubs.HubDispatcher+&lt;&gt;c__DisplayClass1a`1[[SignalR.Hubs.IDisconnect, SignalR]])-&gt;
    0000000185a13640(SignalR.Hubs.HubDispatcher)-&gt;
    000000011f655ed0(SignalR.InProcessMessageBus)-&gt;
    000000011f656680(System.Collections.Concurrent.ConcurrentDictionary`2[[System.String, mscorlib],[SignalR.Infrastructure.LockedList`1[[System.Action`1[[System.Collections.Generic.IList`1[[SignalR.InMemoryMessage`1[[System.UInt64, mscorlib]], SignalR]], mscorlib]], mscorlib]], SignalR]])-&gt;
    0000000237580080(System.Object[])
  RSP:57ae1a0:Root:  000000012acea438(MyApp.Newsfeed.Hubs.NewsfeedHub)-&gt;
    000000012acea5f8(SignalR.GroupManager)-&gt;
    0000000185a17328(SignalR.Connection)-&gt;
    000000011f655ed0(SignalR.InProcessMessageBus)-&gt;
    000000011f656680(System.Collections.Concurrent.ConcurrentDictionary`2[[System.String, mscorlib],[SignalR.Infrastructure.LockedList`1[[System.Action`1[[System.Collections.Generic.IList`1[[SignalR.InMemoryMessage`1[[System.UInt64, mscorlib]], SignalR]], mscorlib]], mscorlib]], SignalR]])-&gt;
    0000000237580080(System.Object[])
  </code></pre>
  
  <p>In my application, I am keeping a list of clients in a ConcurrentDictionary and remove client objects as follows:</p>
  
  <pre><code>Newsfeed.ClientList.TryRemove(fromHubClient.Key, out newsfeedClient);
  </code></pre>
  
  <p>I can't see anything wrrong with that, and see many references to <code>SignalR.Infrastructure.LockedList</code>1[[System.Action<code>1[[System.Collections.Generic.IList</code>1[[SignalR.InMemoryMessage<code>1[[System.UInt64, mscorlib]], SignalR]], mscorlib]], mscorlib]], SignalR]</code></p>
  
  <p>Is there still a memory with some leaky memory with SignalR?</p>