Почему данные MemoryStream не высвобождаются из памяти - PullRequest
0 голосов
/ 20 мая 2009

Что-то нужно сделать с помощью следующего кода, чтобы освободить используемую память?

  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 (). Размер процесса все еще увеличивается на хорошие 4 Мб после каждого звонка. Как будто старое изображение хранится в памяти.

Ответы [ 5 ]

3 голосов
/ 20 мая 2009

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)
2 голосов
/ 20 мая 2009

MemoryStream реализует интерфейс IDisposable, поэтому вы должны вызывать Dispose для этого объекта, когда закончите с ним:

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

Я полагаю, ваш вывод был правильным; изображение (в потоке памяти) остается в памяти.

Обновление: как отметил Марк, 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 голосов
/ 20 мая 2009

Попробуйте это:

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
1 голос
/ 20 мая 2009

Я знаю, что уже дал один ответ, но я думал с тех пор ...

Вы сказали, что эту форму никогда не следует утилизировать. В таком случае, когда именно происходит загрузка изображения? Мой предыдущий ответ предполагал, что это было во время показанного события. Однако, если это происходит во время события Load , это должно произойти только один раз.

То есть, если не создается более одного экземпляра формы. Если это так, и предыдущая форма не используется повторно, то в итоге вы загружаете в память несколько копий одной и той же формы, каждая со своей копией изображения.

0 голосов
/ 20 мая 2009

Вы можете попробовать

set objImage = nothing
set objwebClient = nothing

Часто, как и в случае с ADO, если вы явно не установите для него значение ничего, оно не будет выпущено должным образом.

...