2010-05-08 39 views
8

Tôi đang tạo nhiều điều khiển tùy chỉnh và thêm chúng vào FlowLayoutPanel. Ngoài ra còn có một ContextMenuStrip được tạo ra và phổ biến tại thời điểm thiết kế.Rò rỉ bộ nhớ với ContextMenuStrip

Mỗi khi điều khiển được thêm vào bảng, nó có thuộc tính ContextMenuStrip được gán cho menu này, để tất cả các điều khiển "chia sẻ" cùng một menu. Nhưng tôi nhận thấy khi các điều khiển được loại bỏ khỏi bảng điều khiển và xử lý, bộ nhớ được sử dụng trong Trình quản lý tác vụ không giảm. Nó tăng khoảng 50kB mỗi lần điều khiển được tạo và được thêm vào bảng điều khiển bố cục.

Tôi đã tải xuống bản dùng thử của .NET Memory Profiler và nó cho thấy có tham chiếu đến dải menu treo xung quanh sau khi các điều khiển đã được xử lý. Tôi đã thay đổi mã để thiết lập rõ ràng thuộc tính ContextMenuStrip thành null trước khi xử lý điều khiển, và yep, bộ nhớ hiện đã được giải phóng. Tại sao điều này? GC có nên làm sạch loại điều này không?

+0

http://connect.microsoft.com/VisualStudio/feedback/details/116059/contextmenustrip-memory-leak – CharithJ

Trả lời

5

Nếu bạn xem xét thuộc tính ContexmenuStrip của điều khiển, bạn sẽ thấy rằng trình cài đặt đăng ký điều khiển cho sự kiện được phân phối của MenuStrip, tạo một tham chiếu ngược từ MenuStrip đến điều khiển.

Điều này có nghĩa là đây là trường hợp điển hình của sự kiện có thể truy cập và bạn đã tìm thấy giải pháp: đặt thuộc tính ContexmenuStrip thành null.

+0

Cảm ơn Henk. Tôi mới đến C# nhưng nhận được ý chính của những gì bạn có ý nghĩa. Nhưng tại sao lại có quá nhiều bộ nhớ? Sau khi phát hiện ra lỗ hổng này, tôi nhận ra rằng tôi đã không hủy đăng ký một số sự kiện tùy chỉnh trong các lớp của riêng mình trước khi hủy các phiên bản. Và điều đó dường như không gây ra bất kỳ sự tiêu thụ bộ nhớ tăng lên nào. Hay đó là một con thú khác? – Dave

+1

Lưu ý rằng nó không đối xứng, nếu bạn đã xử lý ContextMenu thì sẽ không có vấn đề gì. Tôi sẽ xem xét điều này một lỗi thiết kế có thể xảy ra của ContextMenuStrip, nó lén lút để back-link như thế này. Hãy coi chừng điều đó trong các lớp học của riêng bạn. Nhưng một khi đăng ký lớp là Xử lý không có vấn đề. –

+0

Oh ok. Cảm ơn. Tôi lấy nó đây là một vấn đề hiếm gặp trong khung .net sau đó? Nếu không có sự sử dụng của một hồ sơ bộ nhớ tôi có lẽ sẽ không có nhặt trên con quỷ nhỏ này. – Dave

0

Bạn nên luôn bỏ ContextMenuStrip trong trường hợp bạn tạo nó mỗi lần động. Điều này là bởi vì mỗi lần là một xử lý bản địa được tạo ra, nhưng không bị phá hủy. Điều này có nghĩa là nếu bạn tạo contextmenu và hiển thị nó, sau đó đóng nó và hiển thị lại nó, bạn sẽ chạy ra khỏi tay cầm.