当前位置:  开发笔记 > 编程语言 > 正文

为什么LINQ查询后的GC释放WhereListIterator而不是表示条件的Func?

如何解决《为什么LINQ查询后的GC释放WhereListIterator而不是表示条件的Func?》经验,为你挑选了1个好方法。

我正在研究一个简单的LINQ查询的内存影响,并注意到LINQ查询创建了2个类型Enumerable+WhereListIterator和的额外对象Func.

使用的代码是这样的:

static void Main(string[] args)
{
    // Setting baseline snapshot
    var list1 = new List { 4862, 6541, 7841 };
    var list2 = new List(list1.Count);
    var list3 = new List(list1.Count);

    // First snapshot: LINQ usage
    list2.AddRange(list1.Where(item => item > 5000 && item < 7000));

    // Second snapshot: foreach-loop
    foreach (var item in list1)
    {
        if (item > 5000 && item < 7000)
        {
            list3.Add(item);
        }
    }

    // End gather
    Console.Read();
}

foreach循环之后的快照中,我注意到Enumerable+WhereListIterator对象是垃圾收集但Func仍然在内存中.

为什么这仍然存在?在那个时间点(在Console.Read声明中)我认为没有任何东西仍在引用它,并且探测器强制GC(这就是收集迭代器的原因).

注意:收集其他快照不会改变释放的对象数量,因此不需要Func为下次运行标记为集合.



1> dasblinkenli..:

lambda不是GC-ed的原因是lambda本身的结构:

item => item > 5000 && item < 7000

这个lambda不捕获任何东西,这意味着它可以编译一次,并永远重用.C#发现了这一点,并通过静态缓存它们以利用lambdas来提高性能.

如果你的lambda从它的上下文中捕获了一个变量,那么当它不再需要时就会被垃圾收集.

有关.NET中lambda生存期的更多信息,请参阅此答案.

推荐阅读
勤奋的瞌睡猪_715
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有