0

下面的代码是否需要做一些事情来释放它使用的内存?

  Dim objImage As MemoryStream
  Dim objwebClient As WebClient
  Dim sURL As String = Trim(m_StationInterface.PicLocation)

  objwebClient = New WebClient
  objImage = New MemoryStream(objwebClient.DownloadData(sURL))
  m_imgLiftingEye.Image = Image.FromStream(objImage)

该代码位于一个不应被丢弃的弹出表单上。每次弹出时都会将新图像加载到表单上。但是,每次通过该代码块时,应用程序的进程大小都会继续增长。

我试过 objImage.Close() 和 .Flush(),objWebClient.Dispose()。每次调用后,进程大小仍会增长 4mb。就像旧图像被保存在记忆中一样。

4

5 回答 5

3

Image实现了 IDisposable,因此您应该在将旧图像替换为新图像之前将其处理掉。

类似的东西(请耐心等待,我有一段时间没有使用 VB):

Dim objImage As MemoryStream
Dim objwebClient As WebClient
Dim sURL As String = Trim(m_StationInterface.PicLocation)

objwebClient = New WebClient
objImage = New MemoryStream(objwebClient.DownloadData(sURL))

If m_imgLiftingEye.Image Is Not Nothing Then
    m_imgLiftingEye.Image.Dispose()
End If
m_imgLiftingEye.Image = Image.FromStream(objImage)
于 2009-05-19T20:55:27.603 回答
2

MemoryStream 实现了 IDisposable 接口,因此您应该在使用完毕后对该对象调用 Dispose:

objImage = New MemoryStream(objwebClient.DownloadData(sURL))
m_imgLiftingEye.Image = Image.FromStream(objImage)
objImage.Dispose()

我猜你的结论是对的;图像(在内存流中)确实保留在内存中。

更新:正如 Marc 指出的那样,Image.FromStream 要求流在图像的生命周期内保持打开状态。为了解决这个问题,应该在与图像相同的范围内声明 MemoryStream 变量(作为表单中的字段)。加载图像时,首先应该检查 MemoryStream 是否已经打开,如果是,则在将变量用于新流之前关闭并释放它(假设我们将其称为 m_imageStream)。由于图像还实现了 IDisposable,因此该图像也是如此:

If Not m_imageStream Is Nothing Then
    m_imageStream.Dispose()
End If

If m_imgLiftingEye.Image Is Not Nothing Then
    m_imgLiftingEye.Image.Dispose()
End If

m_imageStream = New MemoryStream(objwebClient.DownloadData(sURL))
m_imgLiftingEye.Image = Image.FromStream(m_imageStream)
于 2009-05-19T20:50:02.763 回答
2

试试这个:

Function GetImage() As Image
    Using wc As New WebClient(), _
          ms As New MemoryStream(wc.DownloadData(m_StationInterface.PicLocation.Trim())

        GetImage = Image.FromStream(ms).Clone()
    End Using
End Function
于 2009-05-19T20:54:41.617 回答
1

我知道我已经给出了一个答案,但从那以后我一直在想......

你说这个表格永远不应该被处理掉。在那种情况下,这个图像加载到底是什么时候发生的?我之前的回答假设它是在表单显示事件期间。但是,如果它在表单加载事件期间,它应该只发生一次。

也就是说,除非创建了多个表单实例。如果是这种情况,并且以前的表单没有被重用,那么您最终会在内存中加载相同表单的多个副本,每个副本都有自己的图像副本。

于 2009-05-19T21:12:33.873 回答
0

你可以试试

set objImage = nothing
set objwebClient = nothing

通常,与 ADO 一样,如果您没有将其显式设置为空,则它不会被正确释放。

于 2009-05-19T20:46:29.200 回答