2010-02-05 40 views
5

Tôi phân tích dự án VB.NET và có một số đối tượng (mẫu con MDI) được xử lý, nhưng không bị xóa bởi GC.Xử lý sự kiện và rò rỉ bộ nhớ

Phân tích MemoryProfiler tìm, trong số những người khác, như sau:.

"Ví dụ này được xử lý và vẫn gián tiếp bắt nguồn bởi một EventHandler này thường chỉ ra rằng EventHandler vẫn chưa đúng loại bỏ và là một nguyên nhân phổ biến của rò rỉ bộ nhớ. Các trường hợp bên dưới là trực tiếp bắt nguồn từ EventHandler (s). Điều tra chúng để nhận được thêm thông tin về sự cố này ... "

Bây giờ, tôi cố gắng tìm hiểu ý nghĩa của điều này và cách khắc phục.

Tôi có biểu mẫu MDI và biểu mẫu con. Biểu mẫu con không được GC thu thập sau khi mở/đóng, rõ ràng vì vẫn còn (gián tiếp?) Được tham chiếu bởi MDIForm EventHandlerList ...

Tôi có thể làm gì và cách khắc phục?

tôi đã cố gắng sửa chữa đề nghị trong this thread, bởi vì đã có một vấn đề với các tài liệu tham khảo MDI trong PropertyStore, bây giờ điều này loại bỏ, nhưng đã xuất hiện các tài liệu tham khảo MDI EventHandlerList mẫu trẻ ...

Sau khi một số mã phân tích tôi đã quan sát một số

AddHandler newMenu.Click, AddressOf ClickMenu 

không có trước RemoveHandler newMenu.Click, AddressOf ClickMenu. Nó có thể là nguyên nhân chính?

Và, một Propos, là Handles

Private Sub ClickMenu(sender as Object, e as EventArgs) Handles newMenu.Click 

tốt hơn mà

RemoveHandler newMenu.Click, AddressOf ClickMenu 
AddHandler newMenu.Click, AddressOf ClickMenu 

từ quan điểm cấp phát bộ nhớ của xem?

+0

Việc cắt mã có thể hữu ích. Đặc biệt là thêm và loại bỏ xử lý sự kiện và xử lý mã. –

+0

Gọi GC.Collect() sau khi xử lý có thực hiện bất kỳ sự khác biệt nào không? Chỉ vì một cái gì đó được xử lý không phải lúc nào cũng có nghĩa là rác được thu gom ngay lập tức. – Ian

+0

Ngoài ra .. đây thực sự là một vấn đề? Đọc một diễn đàn mà bạn liên kết để gợi ý rằng điều này không tệ hơn theo thời gian. Là một vài kb bị rò rỉ thông qua mã MS sẽ có một tác động lớn? – Ian

Trả lời

4

EventHandlerList được sử dụng bởi các lớp cung cấp số lượng lớn sự kiện để xử lý bộ nhớ hiệu quả hơn bằng cách chỉ phân bổ không gian cho trường sao lưu sự kiện khi cần thiết thay vì khi sự kiện được khai báo. Do đó, tất cả các sự kiện cho biểu mẫu chính được lưu trữ ở đó.

Tôi hy vọng biểu mẫu con sẽ được giám sát khi cha mẹ có thể đóng (đây là trường hợp sử dụng phổ biến) và không hủy đăng ký sự kiện FormClosing hoặc FormClosed khi sự kiện đó nhận được sự kiện đó. Tuy nhiên, đó chỉ là một phỏng đoán.Để xác nhận, hãy xem triển khai biểu mẫu con của bạn và tìm tất cả các trường hợp mà nó đăng ký các sự kiện từ biểu mẫu gốc, sau đó đảm bảo có hủy đăng ký tương ứng từ các sự kiện đó.

Cập nhật
Trình xử lý menu bạn thấy không được xóa cũng có thể là gốc của vấn đề bạn thấy. Hãy thử thêm cuộc gọi xóa và xem liệu cuộc gọi có bị rò rỉ hay không.

2

Có một đối tượng khác tham chiếu đến đối tượng cần được xóa bởi GC thông qua trình quản lý sự kiện. Có nghĩa là: có một đối tượng khác vẫn được đăng ký với một sự kiện của đối tượng được xử lý.

Bạn có thể giải quyết vấn đề này bằng cách hủy đăng ký khỏi sự kiện (xóa eventhandlers khỏi sự kiện), khi bạn muốn vứt bỏ đối tượng đó.

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