Nếu phần mềm của tôi có hai trường hợp đối tượng, một trong số đó được đăng ký với các sự kiện của người kia. Tôi có cần phải hủy đăng ký chúng với nhau trước khi chúng mồ côi để chúng được dọn dẹp bởi người thu gom rác không? Hay có lý do nào khác tại sao tôi nên xóa các mối quan hệ sự kiện? Điều gì xảy ra nếu đối tượng được đăng ký là mồ côi nhưng người đăng ký không phải là hoặc ngược lại?Tôi có cần xóa các đăng ký sự kiện khỏi các đối tượng trước khi chúng bị mồ côi không?
Trả lời
Có bạn đã làm. Các nhà xuất bản sự kiện đang giữ các tham chiếu đến các đối tượng và sẽ ngăn chúng khỏi bị thu gom rác.
Hãy xem ví dụ để xem điều gì xảy ra. Chúng tôi có hai lớp học; một người phơi bày một sự kiện, người khác tiêu thụ sự kiện, người kia tiêu thụ sự kiện:
class ClassA
{
public event EventHandler Test;
~ClassA()
{
Console.WriteLine("A being collected");
}
}
class ClassB
{
public ClassB(ClassA instance)
{
instance.Test += new EventHandler(instance_Test);
}
~ClassB()
{
Console.WriteLine("B being collected");
}
void instance_Test(object sender, EventArgs e)
{
// this space is intentionally left blank
}
}
Lưu ý cách ClassB không lưu trữ tham chiếu đến cá thể ClassA; nó chỉ đơn thuần là móc lên một trình xử lý sự kiện.
Bây giờ, hãy xem cách các đối tượng được thu thập. Trường hợp 1:
ClassB temp = new ClassB(new ClassA());
Console.WriteLine("Collect 1");
GC.Collect();
Console.ReadKey();
temp = null;
Console.WriteLine("Collect 2");
GC.Collect();
Console.ReadKey();
Chúng tôi tạo một thể hiện ClassB và giữ tham chiếu đến nó thông qua biến tạm thời. Nó được thông qua một thể hiện mới của ClassA, nơi chúng tôi không lưu trữ một tham chiếu đến nó ở bất cứ nơi nào, vì vậy nó đi ra khỏi phạm vi ngay lập tức sau khi các nhà xây dựng ClassB được thực hiện. Chúng tôi có bộ thu gom rác chạy một lần khi ClassA đã đi ra khỏi phạm vi, và một khi ClassB đã đi ra khỏi phạm vi. Kết quả:
Collect 1
A being collected
Collect 2
B being collected
Kịch bản 2:
ClassA temp = new ClassA();
ClassB temp2 = new ClassB(temp);
temp2 = null;
Console.WriteLine("Collect 1");
GC.Collect();
Console.ReadKey();
temp = null;
Console.WriteLine("Collect 2");
GC.Collect();
Console.ReadKey();
Một ví dụ mới của ClassA được tạo ra và một tham chiếu đến nó được lưu trữ trong biến temp. Sau đó, một thể hiện mới của ClassB được tạo ra, nhận được cá thể ClassA trong temp được truyền cho nó, và chúng ta lưu trữ một tham chiếu đến nó trong temp2. Sau đó, chúng ta thiết lập temp2 thành null, làm cho cá thể ClassB thoát khỏi phạm vi. Như trước đây, chúng tôi có bộ thu gom rác chạy sau mỗi trường hợp đã hết phạm vi. Đầu ra:
Collect 1
Collect 2
B being collected
A being collected
Vì vậy, để kết luận; nếu cá thể cho thấy một sự kiện diễn ra ngoài phạm vi, nó sẽ có sẵn để thu thập rác, bất kể có xử lý sự kiện hay không. Nếu một cá thể có một trình xử lý sự kiện nối với một sự kiện trong một cá thể khác, nó sẽ không sẵn sàng cho việc thu gom rác cho đến khi trình xử lý sự kiện được tách ra, hoặc cá thể mà trình xử lý sự kiện được đính kèm sẵn sàng cho việc thu gom rác.
Bạn chỉ cần mở móc ra sự kiện nếu đối tượng lộ các sự kiện là tồn tại lâu dài, nhưng đối tượng hooking sự kiện này nếu không sẽ là ngắn ngủi (và được thu gom rác thải khá nhanh chóng).
Trong trường hợp này, không hủy bỏ sẽ gây ra những gì số tiền bị rò rỉ bộ nhớ, vì đối tượng sống ngắn của bạn sẽ không thể được GCed - vì sự kiện trong đối tượng tồn tại lâu dài giữ trên một đại biểu, giữ một tham chiếu đến đối tượng sống ngắn. Vì đối tượng sống ngắn này vẫn được tham chiếu bởi đại biểu đó, nó không thể lấy rác.
Sự kiện tĩnh tồn tại lâu dài theo định nghĩa - chúng tồn tại cho đến khi chương trình thoát. Nếu bạn móc một sự kiện tĩnh, bạn chắc chắn sẽ bỏ qua nó khi bạn hoàn thành.
Nếu cả hai đối tượng sắp bị mồ côi, bạn không cần phải tìm thiết bị.
Đăng ký kết quả sự kiện có liên quan chặt chẽ đến người đăng ký. Điều này là bởi vì, dưới sự bao gồm, các sự kiện là các đại biểu, và các đại biểu cho các phương thức ví dụ là một sự kết hợp của tham chiếu đối tượng và phương thức thực tế. Nếu bạn không hủy đăng ký, nhà xuất bản sẽ tiếp tục duy trì tài liệu tham khảo và các đối tượng đăng ký không bao giờ thực sự mồ côi (và GC'ed) miễn là nhà xuất bản vẫn còn hoạt động.
Điều ngược lại không đúng nghĩa là đối tượng đã đăng ký không có bất kỳ tham chiếu nào đến nhà xuất bản.
- 1. Hibernate có thể xóa các bộ sưu tập mồ côi khi cập nhật một đối tượng tách rời không?
- 2. Tại sao người thu gom rác không tìm ra được khi đối tượng tham chiếu eachother thực sự mồ côi
- 3. Cách thanh lịch để xóa các hàng mồ côi?
- 4. JPA CascadeType.ALL không xóa trẻ mồ côi
- 5. EF có thể tự động xóa dữ liệu bị mồ côi, nơi cha mẹ không bị xóa không?
- 6. Tôi có cần tách các sự kiện trong jQuery khi tôi xóa các phần tử
- 7. Tại sao các sự kiện đã đăng ký biến mất khi phần tử bị xóa khỏi DOM?
- 8. Đăng ký sự kiện khi tạo đối tượng trong C#
- 9. Tại sao không NHibernate xóa trẻ mồ côi đầu tiên?
- 10. SQLAlchemy xoá nhiều trẻ mồ côi
- 11. Tôi có cần hủy liên kết sự kiện jquery trước khi xóa phần tử không?
- 12. Hibernate không xóa trẻ mồ côi trên OneToMany
- 13. Tôi có cần xóa các sự kiện khi tắt bằng cách sử dụng logback không?
- 14. Tại sao chúng ta cần đăng ký stackpointer khi chúng tôi đã có đăng ký bộ đếm chương trình?
- 15. Chúng tôi có cần đăng ký * .xcuserstate không?
- 16. tìm các phương thức mồ côi trong codebase
- 17. Backbone Sự kiện: đăng nhập tất cả các sự kiện khi chúng được kích hoạt
- 18. Các đối tượng System.Web.Caching.Cache Dispose có bị xóa khỏi bộ nhớ cache không?
- 19. Chi nhánh mồ côi trong TFS
- 20. Có thể đăng ký các đăng ký sự kiện trong C# không?
- 21. Hibernate xóa trẻ mồ côi khi cập nhật bộ sưu tập
- 22. Trình xử lý sự kiện javascript có cần phải được xóa trước khi xóa phần tử mà chúng được đính kèm không?
- 23. Tôi có phải hủy đăng ký tất cả các trình xử lý sự kiện không?
- 24. Làm thế nào để xóa tất cả các bản ghi mồ côi trong MySQL?
- 25. Tôi có cần đăng ký Ninject.OnePerRequestModule với Ninject.Web.MVC 3.0 không?
- 26. Có thể tìm và xóa các đốm màu mồ côi trong blobstore của công cụ ứng dụng không?
- 27. Tôi có cần phải thoát khỏi các ký tự khi gửi email không?
- 28. python: Cách phát hiện khi chuỗi của tôi trở thành trẻ mồ côi?
- 29. Sự kiện không đăng ký sau khi thay thếWith
- 30. Cách gọi sự kiện trước khi Environment.Exit()?