Barry Anderberg <(E-Mail Removed)> wrote in
news:#(E-Mail Removed):
> Chris,
>
> I am not sure I agree with you. I am familiar with the GC and
> how/when it collects garbage. It collects once the managed heap
> is full, and at some other times. So I wrote the test
> application to deliberately fill the heap to force a garbage
> collection. I also added a button to the form to call
> GC.Collect() and according to the memory profiler, these objects
> have not been disposed. I realize that they have been garbage
> collected, but that does not mean there are no leaks. If
> unmanaged resources are not freed, the garbage collector will
> not do it for you. The unmanaged resources are freed by the
> underlying framework code when the object is disposed, or in the
> finalize method of the class in question. The only thing I can
> assume is that the finalize method is doing the job, but I still
> think it's a bug in the framework that the Dispose method of the
> Font's objects aren't being called. Any class that implements
> IDisposable should have its dispose method called. The finalize
> method is a last resort when the programmer does not call
> Dispose like he should. Isn't that your understanding as well?
>
> Again, you're probably right that there's no leak but it makes
> for considerable confusion when running a memory profiler that
> tracks undisposed objects. We have a major piece of software at
> my job and it is slowly eating up the memory and eating up the
> entire pagefile causing major fragmentation of the pagefile,
> ultimately slowing down the system and causing other remoted
> applications to begin timing out. I've been spending lots of
> time pouring over code and running this memory profiler and I'm
> at a loss as to why this is happening. The FontFamily class is
> only one of many objects that the .NET framework is not
> disposing of even though the classes implement IDisposable.
> That's simply bad programming on the part of Microsoft. One
> thing to note is that we're using the 1.0 Framework which may
> explain these issues. Perhaps the objects are being properly
> disposed of in the newer .NET Framework.
Barry,
I think I duplicated your bug in .Net 1.1.
Depending upon the Font constructor used, each instance of the Font
class creates one or two instances of the FontFamily class for its
own internal use, but never disposes of them.
This code results in two FontFamily instances being created (and not
disposed of):
Font f = new Font("Arial", 10, FontStyle.Bold);
...
f.Dispose();
Whereas passing an existing instance of FontFamily to the Font
constructor only results in one undisposed instance of FontFamily:
FontFamily fontFamily = new FontFamily("Arial");
Font f = new Font(fontFamily, 10, FontStyle.Bold);
...
f.Dispose();
fontFamily.Dispose();
If you want to dig into the .Net framework source code, there is a
great utility called Reflector available at:
http://www.aisto.com/roeder/dotnet/
With it, you can view the decompiled C# source of all of the methods
of the Font and FontFamily classes (and all the rest of the .Net
framework.)
At this point, about the only constructive advice I can offer is the
obvious: minimize the number of instances that don't get properly
disposed. Something like creating a handful of global Font instances
and re-using them throughout the app.
FWIW, here's a short program that demonstrates the problem:
// Compile with "csc /t:exe example.cs"
using System;
using System.Drawing;
using System.Windows.Forms;
namespace TestNamespace
{
public class TestClass
{
[STAThread]
public static void Main()
{
using (Label lblClock = new Label())
{
using (Graphics dc = lblClock.CreateGraphics())
{
// The Font instances get disposed of OK, but
// there will be 2000 undisposed instances of
// FontFamily.
for (int i = 0; i < 1000; i++)
{
dc.Clear(Color.White);
using (Font f = new Font("Arial", 10, FontStyle.Bold))
{
dc.DrawString(DateTime.Now.ToString(
"yyyy MMM dd, hh:mm:ss"), f, Brushes.Black, 5, 0);
}
}
}
}
Console.WriteLine("Done.");
Console.ReadLine();
}
}
}
Chris.
-------------
C.R. Timmons Consulting, Inc.
http://www.crtimmonsinc.com/