Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么LINQ查询后的GC释放WhereListIterator而不是表示条件的Func?_C#_.net_Linq_Garbage Collection - Fatal编程技术网

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

C# 为什么LINQ查询后的GC释放WhereListIterator而不是表示条件的Func?,c#,.net,linq,garbage-collection,C#,.net,Linq,Garbage Collection,我正在研究一个简单LINQ查询对内存的影响,并注意到LINQ查询创建了两个额外的对象,类型分别为Enumerable+WhereListIterator和Func 使用的代码如下所示: static void Main(string[] args) { // Setting baseline snapshot var list1 = new List<int> { 4862, 6541, 7841 }; var list2 = new List<int&

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

使用的代码如下所示:

static void Main(string[] args)
{
    // Setting baseline snapshot
    var list1 = new List<int> { 4862, 6541, 7841 };
    var list2 = new List<int>(list1.Count);
    var list3 = new List<int>(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();
}
static void Main(字符串[]args)
{
//设置基线快照
var list1=新列表{486265417841};
var list2=新列表(list1.Count);
var list3=新列表(list1.Count);
//第一个快照:LINQ使用情况
列表2.AddRange(列表1.Where(item=>item>5000&&item<7000));
//第二个快照:foreach循环
foreach(列表1中的变量项)
{
如果(项目>5000和项目<7000)
{
清单3.添加(项目);
}
}
//末端聚集
Console.Read();
}
foreach
循环后的快照中,我注意到
Enumerable+WhereListIterator
对象被垃圾收集,但
Func
仍在内存中

为什么这个还留着?此时(在
控制台.Read
语句中),我认为没有任何东西仍在引用它,并且探查器已强制执行GC(这就是收集迭代器的原因)


注意:收集其他快照不会改变释放的对象数量,因此这不是将
Func
标记为收集以供下次运行的问题。

lambda未被GC ed的原因是lambda本身的结构:

item => item > 5000 && item < 7000
item=>item>5000&&item<7000
这个lambda不捕获任何东西,这意味着它可以被编译一次,并且永远被重用。C#发现了这一点,并通过静态缓存lambda来利用它们来提高性能

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


有关.NET中lambda寿命的更多信息,请参阅。

Perfect,这一点和链接的答案解释了一切。重新打开问题时的评论:虽然链接的问题肯定是相关的,但此问题询问了一个具体案例,并提供了一个演示来演示发生了什么。@DasbLinkedLight fair,那就让它开着吧。