Garbage Collector and unmanaged resources

P

PromisedOyster

There are various contradictory newsgroup postings on this issue, but I
would really like a definitive answer from the .NET gurus out there?

We have various WinForms that contain multiple Icons and Bitmaps that
are loaded onto the form dynamically, eg control.Icon = ;. Should we
explicitly Dispose of these unmanaged resources when the form closes OR
should we leave it up to the garbage collector to remove these (and
will it definitively remove them?).

Currently, we are NOT disposing of them. However, we are experiencing
intermittent GDI errors, eg A generic error occurred in GDI+,
particularly on terminal server environments AND the GDI count (and
memory usage) grows as the user uses the system, but does not reduce
when the user closes the forms, despite forcing a call to
System.GC.Collect() when closing the form. Perhaps these issues are not
even related?

My understanding was that the recommended way was to let the garbage
collector sort things out, but I am now starting to wonder if this is
correct with applications that use a lot of unmanaged resources.
 
L

Laura T.

GC calls finalizers, not Dispose. And the way GC works, there is no
guarantee when it will do it.
GC might not even fire after a long time, so the unmanaged resources remain
there for a long time.

This is why there is a need for an explicit release of unmanaged resources,
called dispose pattern,
embodied by the Dispose method.

WinForms runtime does call Dispose, when the form is closed (expect some
cases for MDI applications)
for all the controls it has, so you do not need to call Dispose explicitly.

If you do control.Icon=LoadFromFile() you create a new Icon object that is
holding a OS handle in it.
If you repeate the instruction, you in effect, create a new object with OS
handle in it but you leave the previous
object 'hanging' around. The previous object is could be marked unreacheable
so it will be collected someday, and finalized
someday+later. And it's only on someday+later that the OS handle will be
released.

You is why should call Control.Icon.Dispose() before assigning the new icon
for it (if it's not null).
This way you release the object and it's handle immediatly.

Whenever feasible, Dispose correctly (=explicitly and early). It helps to
keep the environment clean.

Laura
 
S

Stoitcho Goutsev \(100\)

PromisedOyster,

You should dispose bitmaps and icons as soon as you finish using them.
However for icons that are loaded as a control's icon I don't think you
should worry disposing them explicitly.

Keep in mind that modeless forms (shown with Form.Show) are disposed upon
close where modal dialogs (shown with Form.ShowDialog) are not and need to
be disposed manually otherwise they will be lurking alive in the memory and
probably leaking resources. If you are not reusing modal dialogs dispose
them when the user closes a dialog and the data is extracted.
 
B

Bruce Wood

I agree with Stoitcho, I think. :)

If the Designer has generated the code to assign an Icon to a control
or a form, then I don't believe that it bothers to put code in the
form's Dispose method to dispose of those icons.

However, if you're loading the icon or image yourself, then you should
put appropriate code in your form's Dispose method to dispose of them.
As Laura said, the earlier you Dispose of them, the better, from a
memory perspective.
 
S

Stoitcho Goutsev \(100\)

There is even more to that. Objects like bitmaps for example keeps almost
all of their wheight in the unmanaged heap. The GC doesn't care about it, it
cares only for the managed heap where the small Bitamap object leaves (all
its data is in the unamaned heap). So it is possible that unreferenced
bitmaps doesn't put preasure on the managed heap, thus the GC won't kick in
and objects won't be finalized.

To solve this problem in .NET2.0 GC class introduces new pair of methods
AddMemoryPressure/RemoveMemoryPressure that can be used when the applciation
expects to use objects that allocate large chunks of unmanaged memory.
 

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