这很有趣。我们花了最后一天尝试修补以下(遗留)代码的问题,这些代码继续增加其流程大小。这是在Visual Studio 2003中完成的。
我们有一个表单,我们在其上显示一个图像(来自MemoryStream)和一些文本和一个按钮。没有什么花哨。看起来像这样:
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
此表单经常关闭并打开。每次重新打开时,进程内存使用量大约增加5mb。表单关闭时,它不会回退到以前的用法。资源仍然为未引用的表单分配。表单呈现如下:
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)
稍后在关闭后从表单中删除控件:
Me.Controls.Clear()
现在。我们尝试了很多东西。我们发现Disposing什么也没做,事实上,IDisposable接口实际上并没有触及内存。如果我们每次都不创建新的CJ5Form_PTOperatorAcknowledgement表单,则流程大小不会增长。但是将新图像加载到该表单中仍会导致进程大小不断增长。
任何建议都将不胜感激。
答案 0 :(得分:2)
您必须处置您的WebClient对象以及可能不再需要的任何其他托管非托管资源。
objImage = New MemoryStream(objwebClient.DownloadData(sURL))
objwebClient.Dispose() ' add call to dispose
更好的代码方法是使用'using'语句:
using objwebClient as WebClient = New WebClient
objImage = New MemoryStream(objwebClient.DownloadData(sURL))
end using
有关详细信息,请在google和stackoverflow上搜索“Dispose”和“IDisposable”模式实现。
最后一个提示:如果可能,请不要使用内存流。直接从文件加载图像,除非您需要将其保存在RAM中。
修改强>
如果我正确理解你的代码,也许这样的东西会起作用:
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
答案 1 :(得分:0)
我不知道为什么会泄漏,但我可以建议您使用.NET Memory Profiler。如果您使用它运行应用程序,它将使您非常了解哪些对象未被处理,并帮助您解决原因。它有免费试用,但值得购买。