Jer*_*vel 10 .net c# linq garbage-collection
我正在研究一个简单的LINQ查询的内存影响,并注意到LINQ查询创建了2个类型Enumerable+WhereListIterator<Int32>和的额外对象Func<Int32, Boolean>.
使用的代码是这样的:
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();
}
Run Code Online (Sandbox Code Playgroud)
在foreach循环之后的快照中,我注意到Enumerable+WhereListIterator<Int32>对象是垃圾收集但Func<Int32, Boolean>仍然在内存中.
为什么这仍然存在?在那个时间点(在Console.Read声明中)我认为没有任何东西仍在引用它,并且探测器强制GC(这就是收集迭代器的原因).
注意:收集其他快照不会改变释放的对象数量,因此不需要Func为下次运行标记为集合.
das*_*ght 11
lambda不是GC-ed的原因是lambda本身的结构:
item => item > 5000 && item < 7000
Run Code Online (Sandbox Code Playgroud)
这个lambda不捕获任何东西,这意味着它可以编译一次,并永远重用.C#发现了这一点,并通过静态缓存它们以利用lambdas来提高性能.
如果你的lambda从它的上下文中捕获了一个变量,那么当它不再需要时就会被垃圾收集.
有关.NET中lambda生存期的更多信息,请参阅此答案.
| 归档时间: |
|
| 查看次数: |
335 次 |
| 最近记录: |