Tôi đã xem xét tác động bộ nhớ của truy vấn LINQ đơn giản và nhận thấy rằng truy vấn LINQ đã tạo thêm 2 đối tượng thuộc loại Enumerable+WhereListIterator<Int32>
và Func<Int32, Boolean>
.Tại sao một GC sau một truy vấn LINQ miễn phí các WhereListIterator nhưng không phải là Func đại diện cho điều kiện?
Mã được sử dụng là:
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();
}
Tại ảnh chụp sau khi foreach
loop Tôi nhận thấy rằng đối tượng Enumerable+WhereListIterator<Int32>
là thu gom rác nhưng Func<Int32, Boolean>
vẫn còn trong bộ nhớ.
Tại sao điều này vẫn được lưu giữ? Tại thời điểm đó trong thời gian (tại câu hỏi Console.Read
) Tôi không nghĩ rằng bất cứ điều gì vẫn còn tham chiếu nó và một GC đã bị buộc bởi profiler (đó là lý do tại sao các iterator được thu thập).
Lưu ý: thu thập thêm ảnh chụp nhanh không làm thay đổi số lượng đối tượng được giải phóng, vì vậy không phải là vấn đề của Func
được đánh dấu để thu thập cho lần chạy tiếp theo.
Nhận xét về việc mở lại câu hỏi: mặc dù câu hỏi được liên kết chắc chắn có liên quan, câu hỏi này yêu cầu về một trường hợp cụ thể và cung cấp bản trình diễn để minh họa những gì đang diễn ra. – dasblinkenlight
@dasblinkenlight đủ công bằng, chúng ta hãy giữ nó mở sau đó. –