为什么这会导致内存泄漏?

发布于 2024-07-22 19:28:42 字数 1872 浏览 6 评论 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()

现在。 我们已经尝试了很多事情。 我们发现 Dispose 不执行任何操作,事实上,IDisposable< /a> 界面实际上并不接触内存。 如果我们不每次都创建新的 CJ5Form_PTOperatorAcknowledgement 表单,则进程大小不会增长。 但是将新图像加载到该表单中仍然会导致进程大小不断增长。

任何建议,将不胜感激。

This is interesting. We've spent the last day attempting to patch a problem with the following (legacy) code that continues to grow its process size. This is done in Visual Studio 2003.

We have a form on which we display an image (from MemoryStream) and some text and a button. Nothing fancy. Looks something like this:

  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

This form is frequently closed and opened. Each time it is re-opened, the process memory usage grows by roughly 5mb. When the form is closed, it doesn't drop back down to its previous usage. The resources remain allocated for the unreferenced form. The form is rendered like this:

      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)

The control is later removed from the form after closing:

Me.Controls.Clear()

Now. We've tried very numerous things. We've discovered that Disposing does nothing, and, indeed, the IDisposable interface doesn't actually touch memory. If we don't create a new CJ5Form_PTOperatorAcknowledgement form each time, the process size does NOT grow. But loading a new image into that form still causes the process size to continually grow.

Any suggestions would be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

最偏执的依靠 2024-07-29 19:28:42

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

I don't know why specifically that is leaking, but I can recommend that you look at using the .NET Memory Profiler. If you run your application using that, it will give you a very good idea of what objects are not being disposed and help you troubleshoot why. It's got a free trial, but it's well worth the purchase.

弃爱 2024-07-29 19:28:42

您必须处置您的 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

You have to dispose of your WebClient object and any other managed unmanaged resources that may no longer be needed.


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

An even better way to code that would be to use a 'using' statement:


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

For further information please search for 'Dispose' and 'IDisposable' pattern implementation on google and stackoverflow.

One last hint: Don't use a memory stream if possible. Load the image directly from file unless you need to keep it in RAM.

Edit

If I understand your code correctly perhaps something like this would work:


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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文