I have a parent object that has a reference to a child object and additionally the parent has an event handler that listens to an event of the child object.
If all references to the parent object will be released, will the memory used through the parent and the child be freed through GC? (Assuming that no more references neither to the child nor to the parent exist).
class ParentClass {
ChildClass _childClass;
public ParentClass(ChildClass childClass) {
_childClass = childClass;
childClass.SomeEvent += ChildClass_SomeEvent;
}
void ChildClass_SomeEvent(object sender, SomeEventArgs e) {
}
}
Please note, I'm aware that GC does not react immediately. My question is not if the memory is freed immediatly after releasing the parent object. My question is, if the memory is released anyhow.
Update
For me it seems that the answer is a clear yes, GC is able to resolve this circular reference. But for all who read this post and have a similar question, take care to not leave event-registration open. It's only a special example in which the registration is no problem. In other cases, event-registrations may cause serious memory leaks.
A very good resource covering this question was provided by vilx: http://www.interact-sw.co.uk/iangblog/2004/07/07/circulareventrefs
The garbage collector allocates and frees virtual memory for you on the managed heap. If you're writing native code, you use Windows functions to work with the virtual address space. These functions allocate and free virtual memory for you on native heaps.
The garbage collector will free the memory after you "destroy" the reference. i. 3 Setting the object reference to null. You can use forced garbage collection option but you should use it with care.
The JVM does release back memory under some circumstances, but (for performance reasons) this does not happen whenever some memory is garbage collected. It also depends on the JVM, OS, garbage collector etc. You can watch the memory consumption of your app with JConsole, VisualVM or another profiler.
In Java, the programmer allocates memory by creating a new object. There is no way to de-allocate that memory. Periodically the Garbage Collector sweeps through the memory allocated to the program, and determines which objects it can safely destroy, therefore releasing the memory.
Yes. .NET GC handles circular references without problems (assuming that you are not using unmanaged resources or you implement IDisposable if you do).
Well, if nothing else was using the same instance of _childClass
, yes it would be collected. However, I'm not sure what the implications are of you not detaching the event handler - event handlers left registered are a source of un-GC-able memory leaks in .NET applications - yours is an interesting take on the problem.
Update: turns out my understanding of the memory leak source was backwards. If class A subscribes to class B but does not unsubscribe, then A will only be collected when B is collected (because B's subscription list is keeping A alive). For long lived event sources, this can be a problem for subscribers.
The problem occurs in all object life-spans, but in reality, if B is just as short-lived as A, the leak is not noticed and not usually a problem.
Update 2: in the case of the OP's example, child is the source and parent is the subscriber - the GC can handle this situation - so long as child is not referenced outside of the parent, meaning child is not elligible for collection (this will keep the parent alive).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With