Why this does not cause a memory leak when event is not unsubscribed

前端 未结 2 993
陌清茗
陌清茗 2020-12-21 00:26

I am trying to understand how events can cause a memory leak. I found a good explaination at this stackoverflow question but when looking at objects in Windg, I am getting

相关标签:
2条回答
  • 2020-12-21 01:00

    The answer is actually in the answer to the question you have linked to:

    When a listener attaches an event listener to an event, the source object will get a reference to the listener object. This means that the listener cannot be collected by the garbage collector until either the event handler is detached, or the source object is collected.

    You are releasing the source object (Person) so the Listener (your Form) is ok to be collected which is why there is no memory leak.

    A Memory leak will occur when this situation is the other way around I.E. when you want to dispose the Form but the event source (your Person object) is still alive holding a reference to it.

    0 讨论(0)
  • 2020-12-21 01:05

    This is a case of a circular reference. The form has a reference to the object that listens to the event through the John field. In turn, John has a reference to the form when its UponWakingUp event was subscribed by the form's constructor.

    Circular references can be a problem in certain automatic memory management schemes, particularly so in reference counting. But the .NET garbage collector doesn't have a problem with. As long as neither the form object nor the Person object have any additional references, the circular reference between the two cannot keep each other alive.

    There are no additional references to either in your code. Which would normally cause both objects to be garbage collected. But the Form class is special, as long as a native Windows window for it exists, an internal reference stored in a handle-to-object table maintained by Winforms keeps the form object alive. Which keeps John alive.

    So the normal way this is cleaned-up is that the user closes the window by clicking the X in the upper right corner. Which in turn causes the native window handle to be destroyed. Which removes the form reference from that internal table. The next garbage collection now sees nothing but the circular reference and collects them both.

    0 讨论(0)
提交回复
热议问题