【问题标题】:List<T> Sort Memory LeakList<T> 排序内存泄漏
【发布时间】:2015-07-27 09:59:05
【问题描述】:

如何在 .NET 中对通用列表进行排序时修复内存泄漏?

private void ManageXmlIndex(XmlDocument xmlDocIndicatorIndex)
{
    indexList = repoManager.ParseIndex(xmlDocIndicatorIndex);
    indexList.Sort((x, y) => y.Created.CompareTo(x.Created));
    view.UpdateIndex(indexList);
}

当我使用linq OrderBy 时也会发生同样的情况。

自定义比较功能能解决问题吗?

该错误是由于List.Sort 而发生的。当我注释掉 Sort 行时,错误消失了。

【问题讨论】:

标签: c# .net linq memory-leaks


【解决方案1】:

您看到的不是内存泄漏。这只是编译器将您的Comparison&lt;IndicatorPropReport&gt; 缓存为调用站点上的static 委托的简单方式,因此您无需为每次调用创建它的实例。

如果你看一下这个简化的例子:

var ints = new List<int> { 3, 2, 1, 8, 5 };
ints.Sort((x, y) => x.CompareTo(y));

看看编译器使用 .NET 反编译器生成了什么:

[CompilerGenerated]
private static Comparison<int> CS$<>9__CachedAnonymousMethodDelegate2;

public static void Main(string[] args)
{
    List<int> ints = new List<int> { 3,2,1,8,5 };
    List<int> arg_51_0 = ints;

    if (Program.CS$<>9__CachedAnonymousMethodDelegate2 == null)
    {
        Program.CS$<>9__CachedAnonymousMethodDelegate2 = 
                new Comparison<int>(Program.<Main>b__1);
    }
    arg_51_0.Sort(Program.CS$<>9__CachedAnonymousMethodDelegate2);
}

[CompilerGenerated]
private static int <Main>b__1(int x, int y)
{
    return x.CompareTo(y);
}

您会看到 Comparsion&lt;int&gt; 被缓存为 static 委托。在您的方法调用中会发生相同的行为。

请注意,此行为是 Roslyn 之前的行为。 Roslyn changes the way delegates are cached 通过创建显示类而不是静态委托,即使没有捕获的变量也是如此。

【讨论】:

  • 我以为是这种情况,但是,我希望在不再需要方法/类之后找到解决方案来释放它。它是在内存中保存整个包含类还是只保存委托?
  • @MiroslavPopov 该类未保存在内存中。它将有资格收集。
【解决方案2】:

我从 Microsoft 支持部门找到了答案:

List&lt;T&gt; 在其静态构造函数中创建一个空数组T。这 数组存储在List&lt;T&gt; 的静态字段中,因此它将一直存在直到 AppDomain 死了。所以,不是内存泄漏。

来源:https://social.msdn.microsoft.com/forums/vstudio/en-US/dee3c1ee-fb63-43f1-88be-413136afe3ed/memory-leak-in-generic-collection

希望能支持你的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-22
    • 1970-01-01
    • 2014-04-12
    • 2012-12-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多