views:

48

answers:

0

I have tried to do this both with GDI+/Invalidate and by using a Line Shape Control. In both cases the memory spirals out of control. To demonstrate, create a windows form application with a timer object which is set to 100ms and enabled and use the following code:

Public Class Form1
   Private Y As Integer
   Private intDirection As Integer = 1

   Private Sub timTest_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles timTest.Tick
      Me.Invalidate()
   End Sub

   Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint

      Dim g As Graphics = Me.CreateGraphics
      Dim myPen As New Pen(Color.Black)

      myPen.Width = 1
      g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
      g.DrawLine(myPen, 10, 10, 200, Y)

      Y += intDirection

      If Y > Me.Height - 20 Then intDirection = -1
      If Y < 0 Then intDirection = 1
      g.Dispose()
      myPen.Dispose()
   End Sub
End Class

So the code above causes a memory leak as the line moves. I think the reason is that there are unmanaged bitmaps created behind the scenes to paint the form which are not being released because on the managed side it is just a pointer.

If I add the following code at the start of the paint function

  Dim intAlloc As Integer = Me.Width * Me.Height * 16
  GC.AddMemoryPressure(intAlloc)

and at the end of the function I call

  GC.RemoveMemoryPressure(intAlloc)

The memory utilization grows a little and shrinks a little but never grows out of control. The AddMemoryPressure and RemoveMemoryPressure seems to alert the GC that it needs to run. Is there a better way to do this or is this correct? The code above is just a simplification for example purposes to get to the root of a problem I have in a larger component with several moving lines. Also is this the best way to calculate the proper value to place in AddMemoryPressure?