Nếu bạn ngụ ý đối tượng (new Foo(i);
), thì sự hiểu biết của tôi là không: điều này không bao giờ được phân bổ trên ngăn xếp; tuy nhiên, nó sẽ chết trong thế hệ zero, vì vậy sẽ rất hiệu quả để thu thập. Tôi không biết mọi góc tối và tối của CLI, nhưng tôi không biết bất kỳ trường hợp nào trong C# sẽ dẫn đến loại tham chiếu được quản lý được phân bổ trên ngăn xếp (chẳng hạn như stackalloc
không thực sự đếm, và rất cụ thể). Rõ ràng trong C++ bạn có thêm một vài tùy chọn, nhưng sau đó nó không phải là một thể hiện được quản lý.
Điều thú vị là, trên MonoTouch/AOT, có thể được thu thập ngay lập tức, nhưng đó không phải là máy ảo CLI chính (và dành cho một trường hợp rất cụ thể).
Đối với biến - đó sẽ thường được trên stack (và tái sử dụng cho mỗi lần lặp) - nhưng nó có thể không phải. Ví dụ, nếu đây là một "iterator block", thì tất cả các biến cục bộ không bị loại bỏ thực sự là các trường trên máy trạng thái do trình biên dịch tạo ra. Phổ biến hơn, nếu biến được "bắt" (thành một phương thức ẩn danh hoặc biểu thức lambda, cả hai dạng này đều đóng), thì biến được chuyển thành một trường trên ngữ cảnh chụp do biên dịch tạo ra, và là riêng biệt trên mỗi vòng lặp lặp lại (từ foo
được khai báo bên trong vòng lặp). Điều này có nghĩa là mỗi số là riêng biệt trên heap.
Đối với i
(biến vòng lặp) - nếu rằng bị bắt, nó được thậm chí thú vị hơn
- trong C# 1.2 chụp không tồn tại, nhưng bởi spec vòng lặp biến là kỹ thuật mỗi lần lặp
- trong C# 2,0-4,0, biến vòng lặp được chia sẻ (gây ra chụp khét tiếng/foreach câu hỏi thường gặp)
- trong C# 5.0 trở lên biến vòng lặp là mỗi lần lặp lại
này chỉ làm cho một sự khác biệt khi biến được chụp, nhưng thay đổi ngữ nghĩa chính xác cách nó biểu hiện trên chụp bối cảnh
Nguồn
2011-11-22 07:43:20
Thông thường, một biến vòng lặp là một loại giá trị, mà được phân bổ trên stack (trong trường hợp của một vòng lặp). –
Tôi có nghĩa là một biến được phân bổ trong vòng lặp. Tôi sẽ cập nhật câu hỏi để làm rõ. – SimonC
Bạn có nghĩa là biến * không? hoặc đối tượng *? (khái niệm rất khác) –