为什么MemoryStream数据没有从内存中释放

时间:2009-05-19 20:42:37

标签: vb.net memory-management memorystream

是否需要使用以下代码来释放它使用的内存?

  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。这就像旧图像保存在内存中一样。

5 个答案:

答案 0 :(得分: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)

答案 1 :(得分: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)

答案 2 :(得分: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

答案 3 :(得分:1)

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

你说这个表格永远不应该被处理掉。在这种情况下,何时发生此图像加载?我之前的回答是假设它是在表格中显示的事件。但是,如果它在Load形式的事件中,它应该只发生一次。

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

答案 4 :(得分:0)

你可以尝试

set objImage = nothing
set objwebClient = nothing

通常,与ADO一样,如果您没有明确地将其设置为空,则无法正确释放。