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

发布于 2024-07-21 05:37:53 字数 520 浏览 6 评论 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。 就像旧的形象被保留在记忆中一样。

Is there something that needs to be done with the following code to release the memory it uses?

  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)

The code is on a popup form that shouldn't ever get disposed. A new image is loaded onto the form every time it pops up. However, the process size for the application continues to grow each time it makes it through that code block.

I've tried objImage.Close() and .Flush(), objWebClient.Dispose(). The process size still grows by a good 4mb after every call. It's like the old image is kept in memory.

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

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

发布评论

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

评论(5

合约呢 2024-07-28 05:37:53

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)

Image implements IDisposable, so you should Dispose the old image before replacing it with a new one.

Something like (bear with me, I haven't used VB in a while):

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)
未央 2024-07-28 05:37:53

尝试这个:

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

Try this:

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
怕倦 2024-07-28 05:37:53

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)

MemoryStream implements the IDisposable interface, so you should call Dispose on that object when you are done using it:

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

I would guess your conclusion was right; the image (in the memory stream) does remain in the memory.

Update: as Marc pointed out Image.FromStream requires the stream to remain open for the lifetime of the image. To resolve this the MemoryStream variable should be declared in same scope as the image (as a field in the form). When loading the image, there should first be a check whether the MemoryStream already is open and if so, close and dispose it before using the variable for a new stream (let's assume that we call it m_imageStream). Since the image also implements IDisposable, the same is true for that one:

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)
耳钉梦 2024-07-28 05:37:53

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

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

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

I know I already gave one answer, but I've been thinking since then...

You said that this form should never be disposed. In that case, when exactly is this image load happening? My previous answer assumed it was during the form Shown event. However, if it's during the form Load event, it should only happen once total.

That is, unless more than one instance of the form is being created. If that's the case, and the previous form isn't being reused, you're ending up with multiple copies of the same form loaded in memory, each with its own copy of the image.

暮光沉寂 2024-07-28 05:37:53

您可以尝试

set objImage = nothing
set objwebClient = nothing

通常,就像使用 ADO 一样,如果您没有明确地将其设置为空,则它不会被正确释放。

You could try

set objImage = nothing
set objwebClient = nothing

Often, like with ADO, if you don't explicitly set it to nothing it doesn't get released properly.

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