C# 替换大型只读字典-垃圾收集

C# 替换大型只读字典-垃圾收集,c#,caching,memory-management,memory-leaks,garbage-collection,C#,Caching,Memory Management,Memory Leaks,Garbage Collection,我们有一个大型的ReadOnlyDictionary,它可以作为高速缓存,用于快速访问大量数据对象 在计时器上,我们定期加载一个替换缓存,然后当它完全加载时,我们用新创建的缓存对象替换现有的缓存对象,以便操作继续进行而不中断 最近,我们遇到了一些内存泄漏问题,我们正在检查的事情之一就是缓存的更换 对我们正在做的事情的简化描述: public class Optimizations { private volatile ReadOnlyDictionary<string, Dicti

我们有一个大型的
ReadOnlyDictionary
,它可以作为高速缓存,用于快速访问大量数据对象

在计时器上,我们定期加载一个替换缓存,然后当它完全加载时,我们用新创建的缓存对象替换现有的缓存对象,以便操作继续进行而不中断

最近,我们遇到了一些内存泄漏问题,我们正在检查的事情之一就是缓存的更换

对我们正在做的事情的简化描述:

public class Optimizations
{
    private volatile ReadOnlyDictionary<string, Dictionary<string, object>> _cache;

    public object GetFromLocalCache(string dataSet, string key)
    {
        object obj;
        Dictionary<string, object> dict;
        if (_cache.TryGetValue(dataSet, out dict) && dict.TryGetValue(key, out obj))
        {
            return obj;
        }

        return null;
    }

    private void OnTimerEvent()
    {
        ReadOnlyDictionary<string, Dictionary<string, object>> newCache = ...
        _cache = newCache;
    }
}
公共类优化
{
私有易失性ReadOnlyDictionary缓存;
公共对象GetFromLocalCache(字符串数据集,字符串键)
{
对象对象对象;
词典词典;
if(_cache.TryGetValue(数据集,输出dict)和&dict.TryGetValue(键,输出obj))
{
返回obj;
}
返回null;
}
私有void OnTimerEvent()
{
ReadOnlyDictionary新缓存=。。。
_cache=newCache;
}
}

我想知道以前在
\u缓存中的数据是否正确地进行了垃圾收集,因为我们似乎要放弃它来创建一个新实例。我们是否应该做一些不同的事情来确保前一个缓存被正确地销毁,并且数据被操作系统回收?

如果返回的实例引用被保存在其他地方,那么代码中缺少的部分(
)可能会很有趣。@ken2k我们已经详细地讨论了这些内容,我们很确定这不是问题。所有内容都从数据库或文件加载到新POCO中。您是否尝试过内存分析工具?这应该指出,当旧的
\u缓存
实例被新实例替换后,代码的哪一部分仍然保留对它的引用。你提供的例子有点难猜。我在这里没有看到明显的问题(虽然您的多线程没有适当的
锁,但它应该与您的问题无关)@ken2k,附带问题,如果没有写入该字典(它是只读的),为什么要锁定?您的字典以字节计有多大。我这样问是因为字典在内部使用数组。如果您的字典太大,默认情况下可能会将它们放在LOH(大对象堆)上。这可能是因为LOH在默认情况下不是在集合上压缩的。此外,任何字符串文本都不会被收集并被拘留。如果使用字符串作为键,我会小心使用的文本数量。