Weird Dispose/Finalize behavior

X

xtravar

I was having trouble tracking down a memory leak in my application, and
after a lot of mucking around I found out that some objects that
inherit from UserControl were not being finalized. Now, there were no
references to these objects... I know this for sure. Multiple calls to
the GC had no effect, either.

I found that UserControl's Dispose() method must be calling
GC.SuppressFinalize(this)...

This code does not work:
GC.ReRegisterForFinalize(this);
base.Dispose();

This code works (the object is Finalized):
base.Dispose();
GC.ReRegisterForFinalize(this);

Is this a bug, or does this behavior serve some sort of purpose? Has
anyone else experienced this? Can someone from Microsoft confirm or
deny this?

Compact Framework 2.0, Visual Studio 2005, testing on an iPAQ.
 
I

Ilya Tumanov [MS]

You should not rely on finalizes to free up native resources for you as they
are not guaranteed to run.

Your control should implement IDisposable and your application should
explicitly call Dispose() instead.


--
Best regards,

Ilya

This posting is provided "AS IS" with no warranties, and confers no rights.

*** Want to find answers instantly? Here's how... ***

1. Go to
http://groups-beta.google.com/group/microsoft.public.dotnet.framework.compactframework?hl=en
2. Type your question in the text box near "Search this group" button.
3. Hit "Search this group" button.
4. Read answer(s).
 
X

xtravar

First of all, the System.Windows.Forms.UserControl class does implement
IDisposable. It is provided by Microsoft. I am not adding my own
unmanaged resources.

Second of all, my problem was that the GC was not collecting the
object... ever. OutOfMemoryException after a few calls to new.
Managed resouces are not being freed by the garbage collector.

Thirdly, I did call Dispose on it. That still does not alleviate the
fact that the object is still in memory and the garbage collector never
picks it up. Look at my code below again, and you will see that I call
Dispose in both scenarios - it's not unmanaged memory that I am worried
about.

Perhaps I am misunderstanding something, but I thought Finalize needs
to be called before managed memory can be freed by the garbage
collector. On my inherited UserControl, Finalize is only called by the
garbage collector in the second snippet of code, but not the first.

Thanks,
Mike
 
I

Ilya Tumanov [MS]

1. Correct, but it's up to you to override it so it would do the right
thing. If you're not using unmanaged resources directly, perhaps you're
using managed classes with such resources (e.g. Bitmap) and not disposing of
them properly? Couple 5MP bitmaps would easily cause out of memory
exception.

2. It might be a bug in GC. Or, more likely, it might be a live reference to
your objects somewhere or it might be classes which are not disposed of
properly used in your control.

3. Since you're not overriding dispose, calling it might fail to produce
desired effect.



As to Finalize, Dispose() would call SuppressFinalize() so your code works
as it should:



GC.ReRegisterForFinalize(this); // Enables Finalize

base.Dispose(); // Disables Finalize. Status - disabled and would not run.



base.Dispose(); // Disables Finalize

GC.ReRegisterForFinalize(this); // Enables Finalize. Status - enable and
will run.




--
Best regards,

Ilya

This posting is provided "AS IS" with no warranties, and confers no rights.

*** Want to find answers instantly? Here's how... ***

1. Go to
http://groups-beta.google.com/group/microsoft.public.dotnet.framework.compactframework?hl=en
2. Type your question in the text box near "Search this group" button.
3. Hit "Search this group" button.
4. Read answer(s).
 

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

Top