Objects don't get Garbage Collected

  • Thread starter Thread starter Retep
  • Start date Start date
R

Retep

Hi all,

hopefully someone can answer the following mystery for me:

I have the following (simplified) application setup:

Main Form
|
Form
|
Controller
|
Entity

A Form owns a Controller, a controller owns an Entity (the business object)
Forms are created from the main form.

I have a test setup where my Main Form contains a button to create Forms
(the variable is created locally on method level).
The Form creates a controller in its constructor (and holds this reference
in a private field on class level) and the controller creates an Entity in
its constructor(and holds the reference on class level).

If have created a finalizer in the Entity class that outputs the string
"GCed" to the console.

On the Main Form there's also a button that explicitly calls GC.Collect()
(just for testing purposes).

In my test scenario, I create several Form objects that I subsequently close
using the X button in the titlebar.
I would expect that the objects (Form, controller and Entity) that are now
no longer reachable, would be collected by the GC (which would call the
finalizers of the entities) but this doesn't happen. No matter how many
Forms I create and close and call GC.Collect(), the text "CGed" does not
show up in the console. Only when I close the application itself, I get the
texts "CGed" for each Entity in the console.

Could someone shed some light on why the GC does not collect these objects?
Does the main form somehow keeps referemces to the created Forms, even
though the variable I used to create it was declared locally on method
level?

Any thoughts are appreciated!
 
Retep said:
Hi all,

hopefully someone can answer the following mystery for me:

I have the following (simplified) application setup:

Main Form
|
Form
|
Controller
|
Entity

A Form owns a Controller, a controller owns an Entity (the business
object)
Forms are created from the main form.

First check out

Smart Client Software Factory
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/scsflp.asp

Which is built on top of

Smart Client - Composite UI Application Block
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/cab.asp

For a very capable and reasonably easy UI framework. I mention this because
you appear to be interested in promoting some MVC-type structure to your
project, and CAB is Microsoft's best guidance on how to do that in WinForms.
Also in the framework they have worked through the sometimes tricky
dependency and lifecycle issues in WinForms development.

I have a test setup where my Main Form contains a button to create Forms
(the variable is created locally on method level).
The Form creates a controller in its constructor (and holds this reference
in a private field on class level) and the controller creates an Entity in
its constructor(and holds the reference on class level).

If have created a finalizer in the Entity class that outputs the string
"GCed" to the console.

On the Main Form there's also a button that explicitly calls GC.Collect()
(just for testing purposes).

In my test scenario, I create several Form objects that I subsequently
close using the X button in the titlebar.
I would expect that the objects (Form, controller and Entity) that are now
no longer reachable, would be collected by the GC (which would call the
finalizers of the entities) but this doesn't happen. No matter how many
Forms I create and close and call GC.Collect(), the text "CGed" does not
show up in the console. Only when I close the application itself, I get
the texts "CGed" for each Entity in the console.

Could someone shed some light on why the GC does not collect these
objects? Does the main form somehow keeps referemces to the created Forms,
even though the variable I used to create it was declared locally on
method level?

No, it does not. From what you have described. the forms should be
colledted. Event handlers are a common source of unexptected live
references, as Event sources hold refernces to all event listeners. If you
post a repro, someone will explain the behavior.

David
 
Retep,

Finalizers only need to be implemented when you hold onto resources that
need cleaning up (File handles, connections, sockets, etc).

In C#, the Finalize method performs the operations that a standard C++
destructor would do. if you supply a destructor you cannot predict when it
will be called - it will only be executed when the garbage collector runs and
removes it from memory. In actual fact, you can never guarantee that a
destructor will ever be called since we can tell the garbage collector NOT to
call an object's destructor with the SuppressFinalize method of the System.GC
class.

Above all, it doesn't make sense to attempt to "Print out a message" from
within a finalizer.

Peter
 
David,

Thanks for your response.

Your suggestion regarding event handlers lead me to the solution.
Turned out the Databindings that I used to bind controls to properties of
the Entity caused the objects to stay alive, not the event handlers.
This was easily solved by calling Databindings.Clear() for each databound
control in the Close event of the form.

R.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top