5

Should I explicitly clear non-global ConcurrentDictionary when not used anymore, or does GC detect its not used anymore?

This is kind of related: Is ConcurrentBag cause of memory leak?


Edit: The reason I was asking, I had following kind of code (simplified here):

let myMethod() =
  async {
    let myEventList = ConcurrentDictionary<myEventParams, bool>()
    use o = myEvent |> Observable.subscribe(fun e ->
            myEventList.GetOrAdd(e, true) |> ignore)
    let! res = doAsyncThingsCausingEvents()
    myEventList |> Seq.iter(fun (e,_) -> Console.WriteLine "We had " + e.ToString())
    res
  }

...and indeed it leaked memory when called parallel in multiple threads several times.

Tuomas Hietanen
  • 4,650
  • 2
  • 35
  • 43

1 Answers1

2

Interesting question. The ConcurrentDictionary is not IDisposable, so I would expect it to work just like any other object. i.e. when it is not referenced anymore it should be eligible for collection, including any owned items that have no other references.

Doing a quick test by allocating a ConcurrentDictionary, nulling the reference and capturing a memory snapshot suggests that this is indeed the case.

JonasH
  • 28,608
  • 2
  • 10
  • 23