2009-05-19 27 views
0

使用するメモリを解放するには、次のコードを実行する必要がありますか?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も上がります。古いイメージが記憶されているようです。

答えて

3

ImageがIDisposableインターを実装して、あなたは新しいものに交換する前に、古い画像を配置する必要がありますので画像もIDisposableインターを実装しているので、同じことがその1のために真であります。

ような何か(私と一緒にクマ、私はしばらくの間で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) 
+0

私はすでにそれを試して、それは動作しませんでした。 – Daniel

+0

私のコードはまったく同じように見え、プロセスサイズはまだ大きくなります。 – Daniel

+0

私は彼がこれと私の答えをする必要があると思う。 –

0

あなたは明示的にそれが適切に解放されません何にそれを設定しない場合は、ADOと同じように、多くの場合、

set objImage = nothing 
set objwebClient = nothing 

を試みることができます。

+0

ちょうど試しました。記憶は拡大し続けている。 – Daniel

2

作業が完了したときに、あなたがそれを使用して、そのオブジェクト上のDisposeを呼び出す必要がありますので、MemoryStreamをには、IDisposableをインターフェイスを実装しています:

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

私はあなたの結論は正しかったと思います。 (メモリストリーム内の)画像はメモリ内に残る。

更新:Marcが指摘したように、Image.FromStreamはストリームが画像の存続期間中開いたままであることを要求します。これを解決するには、MemoryStream変数をイメージと同じスコープで(フォームのフィールドとして)宣言する必要があります。イメージを読み込むときは、まずMemoryStreamがすでに開いているかどうかをチェックし、そうであれば変数を新しいストリームに使う前にそれを閉じて処分する必要があります(m_imageStreamと呼んだものとしましょう)。これを試してみてください

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) 
+0

私はMemoryStreamがIDisposableを実装しているとは思わない。 – Daniel

+0

それは私の最初の考えでもありましたが、ImageクラスのFromStream()ドキュメンテーションを見てみると、「イメージの存続期間にストリームを開いたままにしておく必要があります。それは良いことではない。要求ライフサイクルのある時点で廃棄が必要な複数のオブジェクトを保持するのではなく、画像をキャッシュしてImageクラスをロードすることをお勧めします。 –

+1

http://msdn.microsoft.com/en-us/library/system.io.memorystream.aspx – Daniel

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 
+0

私はそのショットを与えた。動作しません。 – Daniel

+0

クローニングは、ちょっと賢いアイディアでした。それで機能を作っていた。 – Daniel

1

私はすでに答えを与えたが、私はそれ以来考えてきた知っている...

あなたはこのフォームを決して廃棄しないでください。その場合、正確にこの画像の読み込みが行われるのはいつですか?私の前の答えは、それが「Shown event」という形式であると想定していました。ただし、それがLoadという形式の場合は、合計1回しか発生しません。

つまり、フォームのインスタンスが複数作成されている場合を除きます。その場合、以前のフォームが再利用されていない場合、メモリにロードされた同じフォームの複数のコピーが作成され、それぞれに独自のイメージのコピーが作成されます。

+0

私はそれについても考えましたが、ダイアログフォームが作成されている唯一の場所は読み込み中です。 – Daniel

+0

Activatedイベントでもあります。 –

関連する問題