2011-12-06 23 views
12

Tôi đã đọc về GC trong cuốn sách CLR via C#, cụ thể là khi nào CLR muốn bắt đầu một bộ sưu tập. Tôi hiểu rằng nó phải đình chỉ các chủ đề trước khi một bộ sưu tập xảy ra, nhưng nó đề cập rằng nó phải làm điều này khi con trỏ chỉ dẫn luồng đạt đến một điểm an toàn. Trong trường hợp nó không ở một điểm an toàn, nó sẽ cố gắng nhanh chóng, và nó làm như vậy bởi hijacking luồng (chèn một con trỏ hàm đặc biệt trong ngăn xếp luồng). Đó là tất cả tốt và dandy, nhưng tôi nghĩ rằng chủ đề quản lý theo mặc định được an toàn? Tôi đã bước đầu nghĩ rằng nó có thể đã được đề cập đến các chủ đề không được quản lý, nhưng CLR cho phép các chủ đề không được quản lý tiếp tục thực hiện vì bất kỳ đối tượng nào đang được sử dụng cũng phải được ghim.Hành vi GC và CLR Chủ đề Hijacking

Vì vậy, safe point trong chuỗi được quản lý là gì và cách GC có thể xác định đó là gì?

EDIT:

Tôi không nghĩ mình đủ cụ thể. Theo số this MSDN article, ngay cả khi Thread.Suspend được gọi, luồng sẽ không thực sự bị tạm ngưng cho đến khi đạt được safe point. Nó tiếp tục tuyên bố rằng safe point là một điểm trong việc thực thi luồng mà tại đó một bộ sưu tập rác có thể được thực hiện.

Tôi nghĩ rằng tôi không rõ ràng trong câu hỏi của mình. Tôi nhận ra rằng một Chủ đề chỉ có thể bị đình chỉ tại một điểm an toàn và họ phải bị đình chỉ cho một GC, nhưng tôi dường như không thể tìm ra câu trả lời rõ ràng về điểm an toàn là gì. Điều gì quyết định một điểm trong mã như là an toàn?

+2

An toàn bằng CLR, không phải từ CLR. –

Trả lời

13

'Điểm Safe' là nơi chúng tôi là:

  1. Không có trong một khối catch.
  2. Không bên trong một cuối cùng
  3. Không bên trong một khóa
  4. Không bên gọi p/invoke'd (trong mã quản lý). Không chạy mã không được quản lý trong CLR.
  5. Cây nhớ có thể đi bộ.

Điểm # 5 có đôi chút khó hiểu, nhưng có những lúc cây nhớ sẽ không thể đi bộ được. Ví dụ, sau khi tối ưu hóa, CLR có thể mới một đối tượng và không gán nó trực tiếp cho một biến. Theo GC, đối tượng này sẽ là một đối tượng chết đã sẵn sàng để được thu thập. Trình biên dịch sẽ hướng dẫn GC khi điều này xảy ra để không chạy GC.

Dưới đây là một bài đăng blog trên MSDN với nhiều hơn một chút ít thông tin: http://blogs.msdn.com/b/abhinaba/archive/2009/09/02/netcf-gc-and-thread-blocking.aspx

EDIT: Vâng, thưa ngài, tôi đã sai về # 4. Xem here trong phần 'Điểm an toàn'. Nếu chúng ta ở bên trong phần mã p/invoke (không được quản lý) thì nó được phép chạy cho đến khi nó trở lại mã được quản lý một lần nữa.

Tuy nhiên, theo this MSDN article, nếu chúng tôi ở trong một phần không được quản lý mã CLR, thì nó không được coi là an toàn và chúng sẽ đợi cho đến khi mã trả về được quản lý. (Tôi đã gần, ít nhất).

+0

Ah, điều đó có ý nghĩa rất nhiều, đặc biệt là # 5, toàn bộ cấu trúc bộ nhớ cần ở trạng thái có thể kiểm chứng để GC chạy một bộ sưu tập. Đó là một khái niệm rất đơn giản khi bạn có câu trả lời, nó chỉ đến đó mà tôi đã gặp rắc rối với.Cảm ơn! –

Các vấn đề liên quan