By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
429,423 Members | 1,601 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 429,423 IT Pros & Developers. It's quick & easy.

Objects don't get Garbage Collected

P: n/a
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!


Jul 30 '06 #1
Share this Question
Share on Google+
3 Replies


P: n/a

"Retep" <Re******@chello.nlwrote in message
news:ed***************************@news.chello.nl. ..
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/de...tml/scsflp.asp

Which is built on top of

Smart Client - Composite UI Application Block
http://msdn.microsoft.com/library/de...2/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
Jul 30 '06 #2

P: n/a
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


--
Co-founder, Eggheadcafe.com developer portal:
http://www.eggheadcafe.com
UnBlog:
http://petesbloggerama.blogspot.com


"Retep" wrote:
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!


Jul 30 '06 #3

P: n/a
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.

"David Browne" <davidbaxterbrowne no potted me**@hotmail.comschreef in
bericht news:Ok**************@TK2MSFTNGP02.phx.gbl...
>
"Retep" <Re******@chello.nlwrote in message
news:ed***************************@news.chello.nl. ..
>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/de...tml/scsflp.asp

Which is built on top of

Smart Client - Composite UI Application Block
http://msdn.microsoft.com/library/de...2/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

Jul 30 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.