OnlineGuitarist
asked on
Small app with GDI+ using massive memory resources
hi,
I have a form with not much on it.
the below code is simply drawing 5 lines on a pic box.
*** begin ***
Dim bit As Bitmap = New Bitmap(Pic.Width, Pic.Height)
Dim g As Graphics = Graphics.FromImage(bit)
Dim myPen As Pen = New Pen(staffColor, 1)
'staffline1
g.DrawLine(myPen, staffStartPosX, staffStartPosY + staffHeight * 2, Pic.Width - 10, staffStartPosY + staffHeight * 2)
'staffline2
g.DrawLine(myPen, staffStartPosX, staffStartPosY + staffHeight, Pic.Width - 10, staffStartPosY + staffHeight)
'staffline3
g.DrawLine(myPen, staffStartPosX, staffStartPosY, Pic.Width - 10, staffStartPosY)
'staffline4
g.DrawLine(myPen, staffStartPosX, staffStartPosY - staffHeight, Pic.Width - 10, staffStartPosY - staffHeight)
'staffline5
g.DrawLine(myPen, staffStartPosX, staffStartPosY - staffHeight * 2, Pic.Width - 10, staffStartPosY - staffHeight * 2)
Pic.Image = bit
g.Dispose()
*** end ***
Elsewhere on the form, I have a NumericUpDown control which automatically adusts the Staffheight variable from above which would increase the spacing in between the lines....
basically going from this:
________________________
________________________
to:
________________________
________________________
.....
If I adjust the spacing width, the memory for my program increases dramatically. I have had the very small app go from 50Mb of memory up to 500!!! mb of memory just by moving my mousewheel up and down while in the numericUpDown control. The memory will eventually readjust itself down to below 100, but that can take up to 30 seconds or so. Am I doing something wrong with my code? am I not cleaning up properly?
I know there is some kind of garbage collector that automatically cleans up destroyed objects, but it seems to only happen every few seconds, or not enough. I'm assuming the culprits that are filling up the memory are the bitmaps that are being created in the above routine simply because they aren't being destroyed fast enough by the automatic .net garbage collector.
thx.
I have a form with not much on it.
the below code is simply drawing 5 lines on a pic box.
*** begin ***
Dim bit As Bitmap = New Bitmap(Pic.Width, Pic.Height)
Dim g As Graphics = Graphics.FromImage(bit)
Dim myPen As Pen = New Pen(staffColor, 1)
'staffline1
g.DrawLine(myPen, staffStartPosX, staffStartPosY + staffHeight * 2, Pic.Width - 10, staffStartPosY + staffHeight * 2)
'staffline2
g.DrawLine(myPen, staffStartPosX, staffStartPosY + staffHeight, Pic.Width - 10, staffStartPosY + staffHeight)
'staffline3
g.DrawLine(myPen, staffStartPosX, staffStartPosY, Pic.Width - 10, staffStartPosY)
'staffline4
g.DrawLine(myPen, staffStartPosX, staffStartPosY - staffHeight, Pic.Width - 10, staffStartPosY - staffHeight)
'staffline5
g.DrawLine(myPen, staffStartPosX, staffStartPosY - staffHeight * 2, Pic.Width - 10, staffStartPosY - staffHeight * 2)
Pic.Image = bit
g.Dispose()
*** end ***
Elsewhere on the form, I have a NumericUpDown control which automatically adusts the Staffheight variable from above which would increase the spacing in between the lines....
basically going from this:
________________________
________________________
to:
________________________
________________________
.....
If I adjust the spacing width, the memory for my program increases dramatically. I have had the very small app go from 50Mb of memory up to 500!!! mb of memory just by moving my mousewheel up and down while in the numericUpDown control. The memory will eventually readjust itself down to below 100, but that can take up to 30 seconds or so. Am I doing something wrong with my code? am I not cleaning up properly?
I know there is some kind of garbage collector that automatically cleans up destroyed objects, but it seems to only happen every few seconds, or not enough. I'm assuming the culprits that are filling up the memory are the bitmaps that are being created in the above routine simply because they aren't being destroyed fast enough by the automatic .net garbage collector.
thx.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
bit.dispose causes errors in my program. as soon as it's called the area where the bitmap is suppose to appear is blank, and the program halts with a generic error:
An unhandled exception of type 'System.ArgumentException' occurred in system.windows.forms.dll
Additional information: Invalid parameter used.
upon commenting out bit.dispose and bit = nothing, the program functions as normally. myPen.dispose and g.dispose work fine.
An unhandled exception of type 'System.ArgumentException'
Additional information: Invalid parameter used.
upon commenting out bit.dispose and bit = nothing, the program functions as normally. myPen.dispose and g.dispose work fine.
Can you show us the complete code where you draw and how you cause the lines to be updated?
Idle_Mind
Idle_Mind
ASKER
Private Sub pic_Resize(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Pic.Resize
If Pic.Width >= 1 And Pic.Height >= 1 Then
Dim bit As Bitmap = New Bitmap(Pic.Width, Pic.Height)
Dim g As Graphics = Graphics.FromImage(bit)
g.Clear(Pic.BackColor)
bit.Dispose()
bit = Nothing
g.Dispose()
g = Nothing
pnlNotationDrawGrid()
End If
End Sub
Private Sub pnlNotationDrawGrid()
'Draw line on picturebox
'Put a picturebox on the form named pic
Dim i As Short = PrivateVarIntStaffHeight
i = i + 7
Dim bit As Bitmap = New Bitmap(Pic.Width, Pic.Height)
Dim g As Graphics = Graphics.FromImage(bit)
Dim myPen As Pen = New Pen(PrivateVarColStaffColo r, 1)
'staffline1
g.DrawLine(myPen, PrivateVarIntStaffStartPos X, PrivateVarIntStaffStartPos Y + i * 2, Pic.Width - 10, PrivateVarIntStaffStartPos Y + i * 2)
'staffline2
g.DrawLine(myPen, PrivateVarIntStaffStartPos X, PrivateVarIntStaffStartPos Y + i, Pic.Width - 10, PrivateVarIntStaffStartPos Y + i)
'staffline3
g.DrawLine(myPen, PrivateVarIntStaffStartPos X, PrivateVarIntStaffStartPos Y, Pic.Width - 10, PrivateVarIntStaffStartPos Y)
'staffline4
g.DrawLine(myPen, PrivateVarIntStaffStartPos X, PrivateVarIntStaffStartPos Y - i, Pic.Width - 10, PrivateVarIntStaffStartPos Y - i)
'staffline5
g.DrawLine(myPen, PrivateVarIntStaffStartPos X, PrivateVarIntStaffStartPos Y - i * 2, Pic.Width - 10, PrivateVarIntStaffStartPos Y - i * 2)
Pic.Image = bit
'bit.Dispose()
'bit = Nothing
myPen.Dispose()
myPen = Nothing
g.Dispose()
g = Nothing
End Sub
If Pic.Width >= 1 And Pic.Height >= 1 Then
Dim bit As Bitmap = New Bitmap(Pic.Width, Pic.Height)
Dim g As Graphics = Graphics.FromImage(bit)
g.Clear(Pic.BackColor)
bit.Dispose()
bit = Nothing
g.Dispose()
g = Nothing
pnlNotationDrawGrid()
End If
End Sub
Private Sub pnlNotationDrawGrid()
'Draw line on picturebox
'Put a picturebox on the form named pic
Dim i As Short = PrivateVarIntStaffHeight
i = i + 7
Dim bit As Bitmap = New Bitmap(Pic.Width, Pic.Height)
Dim g As Graphics = Graphics.FromImage(bit)
Dim myPen As Pen = New Pen(PrivateVarColStaffColo
'staffline1
g.DrawLine(myPen, PrivateVarIntStaffStartPos
'staffline2
g.DrawLine(myPen, PrivateVarIntStaffStartPos
'staffline3
g.DrawLine(myPen, PrivateVarIntStaffStartPos
'staffline4
g.DrawLine(myPen, PrivateVarIntStaffStartPos
'staffline5
g.DrawLine(myPen, PrivateVarIntStaffStartPos
Pic.Image = bit
'bit.Dispose()
'bit = Nothing
myPen.Dispose()
myPen = Nothing
g.Dispose()
g = Nothing
End Sub
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Have you tried painting a Panel control instead of a Picturebox?
ASKER
Ok, I tried the suggestions earlier, however I wasn't aware of the refresh method which is why I used the bitmaps. I've taken out the pic box and replaced with a panel control, along with the suggested draw methods using only the pen. Since I tried this before with out the .refresh methods, I was having trouble with the graphics updating. With this new info, the program is staying at 20mb or so while performing the same operation that was causing the program to run up to the 500mb mark.
thx so much!
I'll give every point i have, try to split it between you two accordingly.
thx so much!
I'll give every point i have, try to split it between you two accordingly.
Glad we got it working correctly!
=)
Idle_Mind
=)
Idle_Mind
Anytime YOU create an Image, Bitmap, Graphic, Pen or Brush, you should call the dispose method and set the variable to Nothing to release the memory and speed up garbage collection when you are through with it.
bit.Dispose()
bit = Nothing
myPen.Dispose()
myPen = Nothing
g.Dispose()
g = Nothing
Regards,
Idle_Mind