2009-05-21 80 views
0

这很有趣。我们花了最后一天试图用以下(遗留)代码修补问题,这些代码继续增加其进程大小。这是在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不会做任何事情,并且的确,接口实际上并不会触及内存。如果我们每次都不创建新的CJ5Form_PTOperatorAcknowledgement表单,则流程规模不会增长。但是,将新图像加载到该表单中仍然会导致进程大小持续增长。

任何建议,将不胜感激。

回答

2

您必须处置您的WebClient对象以及任何其他可能不再需要的托管非托管资源。


objImage = New MemoryStream(objwebClient.DownloadData(sURL)) 
objwebClient.Dispose() ' add call to dispose 

一个更好的代码方式是使用一个“使用”的语句:


using objwebClient as WebClient = New WebClient  
objImage = New MemoryStream(objwebClient.DownloadData(sURL))  
end using 

欲了解更多信息,请搜索“处置”和“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 
+0

“使用”未添加声明,直到Visual Studio 2005的产权处置是不是这里的问题。我们已经尝试过所有对象处理的变化,但都没有成功。我们也尝试存储文件的本地副本,而不是使用内存流。 – Daniel 2009-05-21 18:07:24

0

我不知道为什么具体是泄漏,但我可以建议你看看使用.NET Memory Profiler。如果你使用它运行你的应用程序,它会给你一个非常好的想法,哪些对象没有被处理,并帮助你解决原因。它有一个免费的试用版,但它非常值得购买。