2009-05-21 79 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。如果你使用它運行你的應用程序,它會給你一個非常好的想法,哪些對象沒有被處理,並幫助你解決原因。它有一個免費的試用版,但它非常值得購買。