ConcurrentDictionary似乎在删除时不标记GC的元素

我惊讶地发现我的应用程序内存占用不断增长 – 运行的时间越长,消耗的内存就越多。 因此,通过windbg一些魔力,我根据ConcurrentDictionary向我的小LRU缓存指出了一个问题。 CD有很多好处,对我来说非常酷(其中一个是它的数据永远不会在LOH中结束)。 TryRemoveTryRemove是用于添加和逐出项目的两种方法。 一些旧元素的!gcroot引导我回到我的缓存。 ILSpy的一些调查让我得出了这样的结论:

TryRemove没有真正删除元素。 它只是改变链表指针以跳过从不将数组元素的值赋值为null 。 这可以防止GC收集旧的被驱逐的对象。

真? 这是一个已知的问题吗? 如果是这样,我唯一的选择是TryUpdate(key, null) ,然后是TryRemove(key) ? 如果是这样,那么我必须锁定ConcurrentDictionary访问,这是矛盾的。

这是ILSpy转储:

 // System.Collections.Concurrent.ConcurrentDictionary private bool TryRemoveInternal(TKey key, out TValue value, bool matchValue, TValue oldValue) { while (true) { ConcurrentDictionary.Tables tables = this.m_tables; int num; int num2; this.GetBucketAndLockNo(this.m_comparer.GetHashCode(key), out num, out num2, tables.m_buckets.Length, tables.m_locks.Length); lock (tables.m_locks[num2]) { if (tables != this.m_tables) { continue; } ConcurrentDictionary.Node node = null; ConcurrentDictionary.Node node2 = tables.m_buckets[num]; while (node2 != null) { if (this.m_comparer.Equals(node2.m_key, key)) { bool result; if (matchValue && !EqualityComparer.Default.Equals(oldValue, node2.m_value)) { value = default(TValue); result = false; return result; } if (node == null) { Volatile.Write<ConcurrentDictionary.Node>(ref tables.m_buckets[num], node2.m_next); } else { node.m_next = node2.m_next; } value = node2.m_value; tables.m_countPerLock[num2]--; result = true; return result; } else { node = node2; node2 = node2.m_next; } } } break; } value = default(TValue); return false; }