2009-05-21 19 views
0

これは興味深いことです。私たちは最後の日に、プロセスサイズを拡大し続ける次のコードで問題を修正しようとしました。これはVisual Studio 2003で行われます。これが原因でメモリリークが発生するのはなぜですか?

イメージを表示するフォーム(MemoryStreamから)とテキストとボタンがあります。何もない。次のような感じです:

Protected Overrides Sub OnLoad(ByVal e As System.EventArgs) 
    MyBase.OnLoad(e) 
    Try 
     m_lblWarning.Visible = False 

     m_grpTitle.Text = m_StationInterface.ProcessToolTitle 
     m_lblMessage.Text = m_StationInterface.ProcessToolMessage 

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

     objwebClient = New WebClient 

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

     m_txtAcknowledge.Focus() 
    Catch ex As Exception 
     '*** This handles a picture that cannot be found without erroring' 
     m_lblWarning.Visible = True 
    End Try 
    End Sub 

このフォームは頻繁に閉じて開いています。再オープンされるたびに、プロセスメモリー使用量は約5MB増加します。フォームが閉じられても、以前の使用状態に戻ることはありません。リソースは未参照のフォームに割り当てられたままです。フォームのようにレンダリングされる:

Me.Controls.Clear() 

を今:

 m_CJ5Form_PTOperatorAcknowlegement = New CJ5Form_PTOperatorAcknowlegement 
     m_CJ5Form_PTOperatorAcknowlegement.stationInterface = m_StationInterface 
     m_CJ5Form_PTOperatorAcknowlegement.Dock = DockStyle.Fill 
     Me.Text = " Acknowledge Quality Alert" 

     '*** Set the size of the form' 
     Me.Location = New Point(30, 30) 
     Me.Size = New Size(800, 700) 

     Me.Controls.Add(m_CJ5Form_PTOperatorAcknowlegement) 

制御については、後に閉じた後に型から除去されます。私たちは非常に多くのことを試みました。 Disposingは何もせず、実際にはIDisposableインターフェイスがメモリに実際に触れていないことがわかりました。毎回新しいCJ5Form_PTOperatorAcknowledgementフォームを作成しないと、プロセス・サイズは増加しません。しかし、新しいイメージをそのフォームにロードすると、依然としてプロセスサイズが継続的に増加します。

何か提案がありがとうございます。

答えて

2

WebClientオブジェクトと、不要になる管理されていない管理されていないリソースを破棄する必要があります。詳細については、GoogleとのStackOverflowの「処分」と「IDisposableを」パターンの実装を検索してください


using objwebClient as WebClient = New WebClient  
objImage = New MemoryStream(objwebClient.DownloadData(sURL))  
end using 

:「を使用して」ステートメントを使用することであろうコードに


objImage = New MemoryStream(objwebClient.DownloadData(sURL)) 
objwebClient.Dispose() ' add call to dispose 

アンでも良い方法。

最後のヒント1つ:可能であれば、メモリストリームを使用しないでください。 RAMに保存する必要がなければ、ファイルから直接イメージをロードします。

編集

私が正しく、おそらくあなたのコードを理解していれば、このようなものは動作します:


Dim objImage As MemoryStream  
Dim objwebClient As WebClient  
Dim sURL As String = Trim(m_StationInterface.ProcessToolPicLocation)  
using objwebClient as WebClient = New WebClient  
    using objImage as MemoryStream = New MemoryStream(objwebClient.DownloadData(sURL))  
    m_imgLiftingEye.Image = Image.FromStream(objImage) 
    end using 
end using 
+0

のVisual Studio 2005処分はここでの問題でなくなるまで「使用」文が追加されませんでした。我々は、成功せずにオブジェクトの処分のすべてのバリエーションを絶対に試みました。また、メモリストリームを使用するのではなく、ファイルのローカルコピーを保存しようとしました。 – Daniel

+0

COMオブジェクトを使用していますか? COMオブジェクトでSystem.Runtime.InteropServices.Marshal.ReleaseComObjectを呼び出す必要があるかもしれませんか? – user79755

+0

COMオブジェクトが含まれていません。これまでに働いたのは、毎回新しいインスタンスを生成するのではなく、同じフォームオブジェクトを再利用することだけです。これは、毎回新しいイメージをフォームにロードする必要がなくても(プロセスサイズが大きくなる)、解決策になります。あたかもガベージコレクタが古いオブジェクトが参照されなくなったことを認識しないかのようです。フォーム上に機能的なものを残すことさえできますが、プロセスのサイズはまだ大きくなります。 – Daniel

0

なぜ具体的に漏れているのか分かりませんが、.NET Memory Profilerを使用することをお勧めします。それを使用してアプリケーションを実行すると、どのオブジェクトが廃棄されていないかを知ることができ、その理由をトラブルシューティングするのに役立ちます。無料トライアルがありますが、購入する価値があります。

関連する問題