为什么这会导致内存泄漏?
这很有趣。 我们花了最后一天的时间尝试修复以下(遗留)代码的问题,该代码继续增加其进程大小。 这是在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不知道具体为什么会泄漏,但我可以建议您查看使用 .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.
您必须处置您的 WebClient 对象和任何其他可能不再需要的托管非托管资源。
更好的编码方法是使用“using”语句:
有关更多信息,请在 google 和 stackoverflow 上搜索“Dispose”和“IDisposable”模式实现。
最后一个提示:如果可能,不要使用内存流。 直接从文件加载图像,除非您需要将其保存在 RAM 中。
编辑
如果我正确理解你的代码,也许这样的事情会起作用:
You have to dispose of your WebClient object and any other managed unmanaged resources that may no longer be needed.
An even better way to code that would be to use a 'using' statement:
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: