I'm trying to run down a memory leak in a windows forms application. I'm looking now at a form which contains several embedded forms. What worries me is that the child forms, in their constructor, take a reference to the parent form, and keep it in a private member field. So it seems to me that come garbage-collection time:
Parent has a reference to the child form, via the controls collection (child form is embedded there). Child form is not GC'd.
Child form has a reference to the parent form, via the private member field. Parent form is not GC'd.
Is this an accurate understanding of how the garbage collector will evaluate the situation? Any way to 'prove' it for testing purposes?
A memory leak starts when a program requests a chunk of memory from the operating system for itself and its data. As a program operates, it sometimes needs more memory and makes an additional request.
The circular reference error message "There are one or more circular references where a formula refers to its own cell either directly or indirectly. This might cause them to calculate incorrectly. Try removing or changing these references, or moving the formulas to different cells."
Circular references aren't a bad thing in itself: you can use them to achieve complex calculations that are otherwise impossible to do, but first you must set them up properly.
Common causes for these memory leaks are: Excessive session objects. Insertion without deletion into Collection objects. Unbounded caches.
Great question!
No, Both forms will be (can be) GC'd because the GC does not directly look for references in other references. It only looks for what are called "Root" references ... This includes reference variables on the stack, (Variable is on the stack, actual object is of course on the heap), references variables in CPU registers, and reference variables that are static fields in classes...
All other reference variables are only accessed (and GC'd) if they are referenced in a property of one of the "root" reference objects found by the above process... (or in an object referenced by a reference in a root object, etc...)
So only if one of the forms is referenced somewhere else in a "root" reference - Then both forms will be safe from the GC.
only way I can think of to "prove" it, (without using memory trace utilities) would be to create couple hundred thousand of these forms, in a loop inside a method, then, while in the method, look at the app's memory footprint, then exit from the method, call the GC, and look at the footprint again.
As others have already said, GC has no problems with circular references. I'd just like to add, that a common place to leak memory in .NET are event handlers. If one of your forms has an attached event handler to another object which is "alive", then there is a reference to your form and the form will not get GC'd.
Garbage collection works by tracking application roots. Application roots are storage locations that contain references to objects on the managed heap (or to null). In .NET, roots are
The list of active roots is maintained by the CLR. The garbage collector works by looking at the objects on the managed heap and seeing which are still accessible by the application, that is, accessible via an application root. Such an object is considered to be rooted.
Now suppose that you have a parent form that contains references to child forms and these child forms contain references to the parent form. Further, suppose that the application no longer contains a references to the parent for or any of the child forms. Then, for the purposes of the garbage collector, these managed objects are no longer rooted and will be garbage collected the next time a garbage collection occurs.
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