Reputation: 11054
This is interesting. We've spent the last day attempting to patch a problem with the following (legacy) code that continues to grow its process size. This is done in Visual Studio 2003.
We have a form on which we display an image (from MemoryStream) and some text and a button. Nothing fancy. Looks something like this:
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
MyBase.OnLoad(e)
Try
m_lblWarning.Visible = False
m_grpTitle.Text = m_StationInterface.ProcessToolTitle
m_lblMessage.Text = m_StationInterface.ProcessToolMessage
Dim objImage As MemoryStream
Dim objwebClient As WebClient
Dim sURL As String = Trim(m_StationInterface.ProcessToolPicLocation)
objwebClient = New WebClient
objImage = New MemoryStream(objwebClient.DownloadData(sURL))
m_imgLiftingEye.Image = Image.FromStream(objImage)
m_txtAcknowledge.Focus()
Catch ex As Exception
'*** This handles a picture that cannot be found without erroring'
m_lblWarning.Visible = True
End Try
End Sub
This form is frequently closed and opened. Each time it is re-opened, the process memory usage grows by roughly 5mb. When the form is closed, it doesn't drop back down to its previous usage. The resources remain allocated for the unreferenced form. The form is rendered like this:
m_CJ5Form_PTOperatorAcknowlegement = New CJ5Form_PTOperatorAcknowlegement
m_CJ5Form_PTOperatorAcknowlegement.stationInterface = m_StationInterface
m_CJ5Form_PTOperatorAcknowlegement.Dock = DockStyle.Fill
Me.Text = " Acknowledge Quality Alert"
'*** Set the size of the form'
Me.Location = New Point(30, 30)
Me.Size = New Size(800, 700)
Me.Controls.Add(m_CJ5Form_PTOperatorAcknowlegement)
The control is later removed from the form after closing:
Me.Controls.Clear()
Now. We've tried very numerous things. We've discovered that Disposing does nothing, and, indeed, the IDisposable interface doesn't actually touch memory. If we don't create a new CJ5Form_PTOperatorAcknowledgement form each time, the process size does NOT grow. But loading a new image into that form still causes the process size to continually grow.
Any suggestions would be appreciated.
Upvotes: 0
Views: 1609
Reputation: 2731
You have to dispose of your WebClient object and any other managed unmanaged resources that may no longer be needed.
objImage = New MemoryStream(objwebClient.DownloadData(sURL))
objwebClient.Dispose() ' add call to dispose
An even better way to code that would be to use a 'using' statement:
using objwebClient as WebClient = New WebClient
objImage = New MemoryStream(objwebClient.DownloadData(sURL))
end using
For further information please search for 'Dispose' and 'IDisposable' pattern implementation on google and stackoverflow.
One last hint: Don't use a memory stream if possible. Load the image directly from file unless you need to keep it in RAM.
Edit
If I understand your code correctly perhaps something like this would work:
Dim objImage As MemoryStream
Dim objwebClient As WebClient
Dim sURL As String = Trim(m_StationInterface.ProcessToolPicLocation)
using objwebClient as WebClient = New WebClient
using objImage as MemoryStream = New MemoryStream(objwebClient.DownloadData(sURL))
m_imgLiftingEye.Image = Image.FromStream(objImage)
end using
end using
Upvotes: 2
Reputation: 45117
I don't know why specifically that is leaking, but I can recommend that you look at using the .NET Memory Profiler. If you run your application using that, it will give you a very good idea of what objects are not being disposed and help you troubleshoot why. It's got a free trial, but it's well worth the purchase.
Upvotes: 0