2009-05-12 39 views

Trả lời

19

Các đối tượng được tham chiếu bởi biến tĩnh sẽ chỉ được thu gom rác khi thu thập AppDomain. Trong các ứng dụng máy khách, thường chỉ có một đơn AppDomain tồn tại trong suốt quá trình xử lý. (Ngoại lệ là khi ứng dụng sử dụng kiến ​​trúc trình cắm - các trình cắm khác nhau có thể được tải trong các khác nhau AppDomain s và AppDomain có thể được tải xuống sau.)

Trong ASP.NET, "AppDomain tái chế" xảy ra định kỳ (vì nhiều lý do khác nhau) - khi điều này xảy ra và các biến tĩnh trong đó AppDomain sẽ không còn hoạt động như gốc GC nữa, và do đó sẽ không ngăn các đối tượng bị thu gom rác.

Nếu bạn đang lo lắng về một đối tượng bị thu gom rác thải trong khi bạn vẫn còn có một tham chiếu đến nó thông qua một biến tĩnh, tuy nhiên, bạn có thể thư giãn. Trong khi bạn có thể truy cập đối tượng, nó sẽ không bị thu gom rác.

+0

Điều này không tạo ra sự thiếu hiệu quả lớn? Tôi thường tạo các phương thức trợ giúp tĩnh riêng. Hoặc, tất cả các phương pháp mở rộng. Tôi tự hỏi bao nhiêu bộ nhớ này tiêu thụ? Nếu tôi có một phương thức trợ giúp cho một đối tượng, tốt hơn là chỉ cần rời khỏi trình trợ giúp như một cá thể sao cho nó sẽ được thu thập? –

+0

@ P.Brian.Mackey: Nếu bạn có các phương pháp tĩnh, bạn nghĩ mình đang tiêu thụ bộ nhớ nào? Nếu bạn có các biến * tĩnh *, bạn đã có trạng thái toàn cầu, thường là một ý tưởng tồi để bắt đầu. Nhưng phương pháp của chính họ là một vấn đề khác. –

+0

Sai lầm của tôi. Tôi giả định phương pháp được tạo ra trên stack/heap như biến làm. Rõ ràng đó không phải là trường hợp. –

5

Thành viên không được thu thập ... Các đối tượng.
Vì vậy, nếu bạn đặt Ref. Nhập thành viên tĩnh vào null, bất kỳ đối tượng nào mà nó đã trỏ trước đó sẽ được thu thập. Nếu không, nó sẽ treo xung quanh cho đến khi AppDomain đi xuống (Mỗi AppDomain có bộ công cụ tĩnh của riêng mình)

0

Thành viên tĩnh đối với loại tham chiếu là tham chiếu, có thể hoặc không thể trỏ đến một phiên bản. Nếu nó trỏ đến một thể hiện, cá thể nói sẽ không được thu thập cho đến khi thành viên tĩnh được dỡ xuống. Nếu loại được tải trong một AppDomain cụ thể, có thể được tải xuống. Nếu không, nó chỉ xảy ra khi ứng dụng bị chấm dứt.

1

Câu trả lời ngắn gọn ... Không; tất cả các triển khai hiện tại của trình thu gom rác .NET sẽ không thu thập các đối tượng được tham chiếu mạnh bởi các trường thành viên lớp tĩnh, cho đến khi miền ứng dụng mà các trường thành viên lớp tĩnh tham chiếu mạnh được liên kết với, bị rách.

Câu trả lời dài hơn ... Có khả năng có; người thu gom rác thải quyết định thu thập một đối tượng về khả năng tiếp cận của đối tượng, không phải đối với vật thể (mạnh hoặc yếu) đối với đối tượng. Về lý thuyết, nếu người thu gom rác có thể xác định rằng không có mã nào yêu cầu một đối tượng nào đó một lần nữa từ một điểm nào đó (nghĩa là đối tượng không thể truy cập được từ bất kỳ đường dẫn mã nào), GC sẽ được phép thu thập đối tượng đó, thậm chí nếu nó vẫn được tham chiếu mạnh mẽ bởi các trường thành viên lớp tĩnh. Điều này là hoàn toàn cho phép, vì bạn sẽ không bao giờ nhận thấy, vì không có mã nào sẽ thử truy cập vào trường thành viên lớp tĩnh giữ tham chiếu đến đối tượng. Bạn có thể hỏi, vậy tại sao tôi quan tâm nếu tôi không bao giờ truy cập lại đối tượng thông qua bất kỳ tài liệu tham khảo mạnh mẽ nào mà tôi nắm giữ? Lý do bạn quan tâm là tác dụng phụ. Ví dụ, bạn có thể giả định bằng cách gán một trường thành viên lớp tĩnh một tham chiếu đến một đối tượng SafeHandle, đại diện cho một tài nguyên không được quản lý, đối tượng SafeHandle sẽ không bao giờ bị đóng và do đó sẽ giữ cho đối tượng không được quản lý nó biểu diễn còn sống. Điều này chỉ đúng đối với việc triển khai hiện tại của GC. Việc triển khai trong tương lai của GC có thể thu thập các đối tượng được tham chiếu mạnh mẽ bởi các trường thành viên lớp tĩnh nếu các đối tượng đó không còn có thể truy cập được bằng bất kỳ mã chương trình còn lại nào.

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