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 什么都不做,事实上,IDisposable接口实际上并没有触及内存。如果我们不每次都创建一个新的 CJ5Form_PTOperatorAcknowledgement 表单,则进程大小不会增长。但是将新图像加载到该表单中仍然会导致进程大小不断增长。

任何建议,将不胜感激。

4

2 回答 2

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

有关更多信息,请在 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
于 2009-05-21T17:57:31.493 回答
0

我不知道具体为什么会泄漏,但我可以建议您查看使用.NET Memory Profiler。如果你使用它来运行你的应用程序,它会让你很好地了解哪些对象没有被释放,并帮助你解决原因。它有免费试用版,但值得购买。

于 2009-05-21T17:52:06.077 回答