为什么导致内存泄漏?

时间:2009-05-21 17:45:29

标签: vb.net visual-studio memory-leaks visual-studio-2003

这很有趣。我们花了最后一天尝试修补以下(遗留)代码的问题,这些代码继续增加其流程大小。这是在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表单,则流程大小不会增长。但是将新图像加载到该表单中仍会导致进程大小不断增长。

任何建议都将不胜感激。

2 个答案:

答案 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。如果您使用它运行应用程序,它将使您非常了解哪些对象未被处理,并帮助您解决原因。它有免费试用,但值得购买。