When does these unsubscribed events memory leak occurs? Should I write destructor or implement IDisposable to unsubscribe an event?
When does these unsubscribed events memory leak occurs? Should I write destructor or implement
Share
Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.
Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.
Lost your password? Please enter your email address. You will receive a link and will create a new password via email.
Please briefly explain why you feel this question should be reported.
Please briefly explain why you feel this answer should be reported.
Please briefly explain why you feel this user should be reported.
Let’s say that A references B. Furthermore, say you think you’re done with B and expect it to be garbage collected.
Now, if A is reachable[1], B won’t be garbage collected, despite the fact that “you’re done with it”. This is, in all essence, a memory leak[2]
If B subscribes to an event in A, then we have the same situation: A has a reference to B via the event handler delegate.
So, when is this a problem? Only when the referencing object is reachable, as mentioned above. In this case, there can be a leak when a Foo instance isn’t used any longer:
The reason why there can be a leak is that the Bar instance passed in the constructor can have a longer lifetime than the Foo instance using it. The subscribed event handler can then keep the Foo alive.
In this case you need to provide a way to unsubscribe from the event to not get a memory leak. One way of doing that is by letting Foo implement IDisposable. The upside of that is that it clearly signals to the class consumer that he need to call Dispose() when done. Another way is to have separate Subscribe() and Unsubscribe() methods, but that doesn’t convey the type’s expectations – they are too optional to call and introduce a temporal coupling.
My recommendation is:
Or alternatively:
On the other hand, when the referencing object isn’t reachable, there can’t be a leak:
In this case any Foo instance will always outlive its composed Bar instance. When a Foo is unreachable, so will its Bar be. The subscribed event handler cannot keep the Foo alive here. The downside of this is that if Bar is a dependency in need of being mocked in unit testing scenarios, it can’t (in any clean way) be explicitly instantiated by the consumer, but needs to be injected.
[1] http://msdn.microsoft.com/en-us/magazine/bb985010.aspx
[2] http://en.wikipedia.org/wiki/Memory_leak