2010-09-07 14 views
6

Nếu có, có cách nào không muốn sử dụng nó trên toàn cầu cho tất cả các sự kiện có dâySự kiện không mong muốn có bị rò rỉ bộ nhớ không?

Chỉnh sửa: Ví dụ: Tôi có các đối tượng, mỗi đối tượng được gắn thẻ với một sự kiện như orm.NatureChanged += Nature_Changed; Tôi gắn thẻ các sự kiện này khi tôi tạo mỗi cá thể orm. Nếu tôi không muốn có nghĩa là như orm.NatureChanged -= Nature_Changed; nó sẽ gây ra rò rỉ bộ nhớ?

+0

Bạn đang hỏi gì? – SLaks

+2

Bạn có nghĩa là một sự kiện không bị bỏ quên? – Bobby

+0

Bạn có hỏi về sự kiện/đại biểu có danh sách yêu cầu trống không? – Oded

Trả lời

5

Không, bởi vì khi bạn unwire một sự kiện, các đại biểu (nó là một đối tượng) được nối trực tiếp với sự kiện này là không còn bắt rễ, và sẽ được thu thập khi GC thấy phù hợp để làm như vậy. Đây là giả định tất nhiên các đại biểu sự kiện không được đính kèm với nhiều trình xử lý, trong trường hợp đó nó sẽ không được thu thập cho đến khi nó không sẵn sàng từ tất cả các sự kiện.

+0

Tuyệt vời! Vì vậy, có cách nào để thư giãn trên toàn cầu nhiều trình xử lý? –

+1

@Avatar: Trừ khi bạn sử dụng sự phản chiếu (và không), không thể truy cập danh sách yêu cầu của một sự kiện từ bên ngoài lớp khai báo. Vì vậy, không. –

+2

Tôi cho rằng bạn có thể đưa ra một số cách theo dõi thủ công mà sự kiện đã được kết nối ở đâu, nhưng điều này sẽ trở thành gánh nặng, và bạn thực sự sẽ không nhận được nhiều từ nó. Bạn có thể sẽ lãng phí bộ nhớ nhiều hơn theo dõi sự kiện để thư giãn hơn là chỉ để cho nó được và để cho gc vứt bỏ nó khi nó cần. – kemiller2002

2

Nó không phải là một rò rỉ bộ nhớ, nó chỉ không móc bất kỳ xử lý cho sự kiện đó nếu họ không có dây, tự động hoặc cách khác. Vì vậy, sự kiện cháy không ai, được làm sạch, và cuộc sống tiếp tục.

chuyện này nói về chủ đề này: How do events cause memory leaks in C# and how do Weak References help mitigate that?

Xem một số thông tin cơ bản ở đây: What does AutoEventWireUp page property mean?

+0

liên kết 3662842 thật tuyệt vời. Thực sự tuyệt vời thực sự. Tôi đã nghĩ đến việc hỏi về lister = null được giải thích trong phiên trả lời. Nó thực sự hữu ích. –

6

Bất kể bạn đang hỏi gì, câu trả lời kỹ thuật cho câu hỏi của bạn là "không". Về mặt kỹ thuật, trừ khi bạn phát hiện ra một lỗi trong CLR, không có "rò rỉ bộ nhớ" thực sự với các đối tượng được quản lý (đó là một phần lớn của những gì làm cho chúng trở thành một điều tốt). Tuy nhiên, để trả lời những gì tôi nghĩ bạn đang thực sự hỏi, có vẻ như bạn đang hỏi một trong hai điều sau:

  1. Có điều gì cần được thực hiện với các sự kiện không có bất kỳ đại biểu nào gắn với họ không ?
  2. Sự kiện có thể ngăn không cho các đối tượng bị dọn dẹp bởi bộ thu gom rác không?

Câu trả lời cho câu hỏi đầu tiên đơn giản là "không". Di chuyển dọc, không có gì để xem ở đây.

Câu trả lời cho câu hỏi thứ hai đã được thảo luận tại đây trên SO và các khu vực khác của web. Phiên bản ngắn gọn là một trình xử lý sự kiện đính kèm có nghĩa là GC sẽ xem xét cá thể đích là "có thể truy cập" bằng cá thể bắn sự kiện. Điều này có thể khiến đối tượng ở lại trong bộ nhớ lâu hơn dự kiến, vì khả năng hiển thị này có phần minh bạch đối với người dùng (nhà phát triển) do cách các đại biểu được xây dựng.

Nói cách khác, nói rằng tôi có hai đối tượng: Nhà sản xuất và người tiêu dùng. Nhà sản xuất bắn một sự kiện mà Người tiêu dùng ... tiêu thụ.

public class Producer 
{ 
    public event EventHandler OmgIDidSomething; 
} 

public class Consumer 
{ 
    public void AttachTo(Producer producer) 
    { 
     producer.OmgIDidSomething += new EventHandler(producer_OmgIDidSomething); 
    } 

    private void producer_OmgIDidSomething(object sender, EventArgs e) 
    { 
     // ... 
    } 
} 

Trong ví dụ này, bất kỳ trường hợp Consumer nơi AttachTo được gọi sẽ vẫn có thể truy cập như xa như GC là có liên quan đến trường hợp của Producer rằng nó gắn liền với hội đủ điều kiện cho việc thu thập, bởi vì các đại biểu đằng sau việc thực hiện sự kiện OmgIDidSomething có tham chiếu đến phiên bản Consumer mà nó tương ứng với.

+0

Câu hỏi của tôi là câu hỏi thứ 2 bạn đã đề cập ở trên. –

2

Nếu bạn có nghĩa là các sự kiện không nhận được không mong muốn có thể gây ra rò rỉ bộ nhớ, câu trả lời là có thể nếu tuổi thọ thực tế của đối tượng giữ đại biểu sự kiện dài hơn nhiều so với thời gian sử dụng hữu ích của đối tượng mà đại biểu đề cập đến.Ví dụ, nếu một bộ đếm của một bộ sưu tập nối một sự kiện CollectionChanged, và một người nào đó để có được các điều tra viên mà không bao giờ xử lý chúng, thì mỗi khi bộ sưu tập được liệt kê (không xử lý điều tra), một đối tượng liệt kê mới sẽ được tạo trong bộ nhớ như bộ sưu tập cơ bản.

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