CreateMeasurementGraphics memory leak

  • Thread starter Thread starter Dave
  • Start date Start date
D

Dave

Hi.

Could someone please tell me how I should correctly dispose of the
CreateMeasurementGraphics reference to stop the memory leak in the
following code:


For x = 1 To 10000
Dim PrintDocument As New Printing.PrintDocument
Dim g As Graphics =
PrintDocument.PrinterSettings.CreateMeasurementGraphics
Dim hdc As IntPtr = g.GetHdc()
g.ReleaseHdc(hdc)
g.Dispose()
PrintDocument.Dispose()
Next



Your help in much appreciated.

Dave
 
Cor Ligthert said:
Hi Dave,

Are you sure it is a memoryleak, the dispose does not free memory, it
set the object in a state that the the Garbage Collector knows that
it can set free.

http://support.microsoft.com/default.aspx?scid=kb;en-us;317866

Did you have a look at that?

I did not follow the link, but what you wrote is wrong. Dispose can free
memory if it's one of the types of unmanaged resources the object allocated.
Dispose also does not free the object to be available for the GC. Dispose
has Nothing to do with GC. At least as long as there's still a reference on
the object, the object won't be collected, even if you called Dispose.
 
Hi Armin,
I did not follow the link, but what you wrote is wrong. Dispose can free
memory if it's one of the types of unmanaged resources the object allocated.
Dispose also does not free the object to be available for the GC. Dispose
has Nothing to do with GC. At least as long as there's still a reference on
the object, the object won't be collected, even if you called Dispose.
Agree, however look at the problem.

There are created 10000 new graphic objects in a single routine which stays
in scoop.

In my idea those objects will not be removed until the routine is ended.

My idea was that maybe force the GC to start can help.

However, never tried it.
And maybe you have a better idea.

Or what I am thinking on writting this, maybe it is just easier to create a
method to create the object, than it will go everytime out of scoop.

Cor
 
Cor Ligthert said:
Hi Armin,
Agree, however look at the problem.

There are created 10000 new graphic objects in a single routine which
stays in scoop.

In my idea those objects will not be removed until the routine is
ended.

g stores *one* reference only.
My idea was that maybe force the GC to start can help.

However, never tried it.
And maybe you have a better idea.

Or what I am thinking on writting this, maybe it is just easier to
create a method to create the object, than it will go everytime out
of scoop.

Yes and no. Going out of scope of course removes the reference because the
variable is destroyed, but in the OP's code, the reference is also removed
because it is overwritten by the next reference. It wouldn't make a big
difference. So, after the loop, before the procedure is left, there is 1
referenced and not collectable object, and 9999 not referenced and
collectable objects. As you know GC.collect (and optionally
gc.waitforpendingfinalizers) could destroy the objects immediatelly and
release memory, but you probably also know that this actually shouldn't be
done because we should rely on the GC and have it do the work when it
"thinks" it's the time.


--
Armin

How to quote and why:
http://www.plig.net/nnq/nquote.html
http://www.netmeister.org/news/learn2quote.html
 
* (e-mail address removed) (Dave) scripsit:
Could someone please tell me how I should correctly dispose of the
CreateMeasurementGraphics reference to stop the memory leak in the
following code:


For x = 1 To 10000
Dim PrintDocument As New Printing.PrintDocument
Dim g As Graphics =
PrintDocument.PrinterSettings.CreateMeasurementGraphics
Dim hdc As IntPtr = g.GetHdc()
g.ReleaseHdc(hdc)
g.Dispose()
PrintDocument.Dispose()
Next

How did you find out that there is a memory leak? Did you have a lookat
the GDI handles in Task Manager?
 
(e-mail address removed) (Herfried K. Wagner [MVP]) wrote in message
How did you find out that there is a memory leak? Did you have a lookat
the GDI handles in Task Manager?

Thanks everyone for your input. I was looking at the mem usage in the
task manager. I suppose Memory leak may not be the correct term for
the problem here, however I couldn't think of a better term do descibe
it as the garbage collector never seems to release the memory, even if
I try to force it to.

If you run the sample code you will quickly see the problem. My
application acts as a print spooler service and memusage eventually
gets to a point where the server blue screens.
 
Dave said:
(e-mail address removed) (Herfried K. Wagner [MVP]) wrote in message


Thanks everyone for your input. I was looking at the mem usage in
the task manager. I suppose Memory leak may not be the correct term
for the problem here, however I couldn't think of a better term do
descibe it as the garbage collector never seems to release the
memory, even if I try to force it to.

If you run the sample code you will quickly see the problem. My
application acts as a print spooler service and memusage
eventually gets to a point where the server blue screens.


Yes, looks like there should be a Dispose method in the Printdocument class
(one that is not inherited). Means I can repro the problem. GDI handles are
reserved but not released (according to taskman), despite calling dispose
and forcing garbage collection.


--
Armin

How to quote and why:
http://www.plig.net/nnq/nquote.html
http://www.netmeister.org/news/learn2quote.html
 
Armin Zingler said:
Yes, looks like there should be a Dispose method in the Printdocument class
(one that is not inherited). Means I can repro the problem. GDI handles are
reserved but not released (according to taskman), despite calling dispose
and forcing garbage collection.

I was hoping my ineptitude was the cause of the problem. Oh well.
Should I report this issue to MS or will one of the MVP's follow it
up?
 
For anyone reading this; as a workaround i've set up a timer to check
that the System.Environment.WorkingSet is under a reasonable amount.
If it's over, the application starts a new instance of itself then
closes. Dodgy but effective.


Regards,

Dave
 
* (e-mail address removed) (Dave) scripsit:
For anyone reading this; as a workaround i've set up a timer to check
that the System.Environment.WorkingSet is under a reasonable amount.
If it's over, the application starts a new instance of itself then
closes. Dodgy but effective.

LOL!
 
Back
Top