2017-02-01 11 views
0

私はあるイベントに基づいて、私はinitializeという新しいフォームベースのダイアログとinitializeというクラスを持っています。このフォームベースのダイアログには、他のコントロールがあります。C#フォームアプリケーションのメモリリーク

dialogが閉じている場合は、フォームに作成されたすべてのコントロールをクリアして削除します。残念ながら、何かが処分されていないか、取り除かれた後でも記憶に残っているようです。

フォームformClassオブジェクト内部ポンプ

class someClass 
{ 
    System.Timers.Timer someTimer; 
    public void CallToChildThread(Object stateInfo) 
    { 
     // check some event 
     // if true, fire event 
    } 
    someClass() 
    { 
      someTimer= new System.Threading.Timer(CallToChildThread, 
            autoEvent, 1000, 250); 
      _show += new EventHandler(eventCheck); 
    } 
    void eventCheck() 
    { 
     formClass formClassObject = new formClass(); //create form 
     formClassObject.someFunction(); // has some other function and does a showDialog on self 
     formClassObject.Dispose(); 
     formClassObject = null; 
    } 
} 

は、FormClosedイベントを取得すると、私は、オブジェクト内のコントロール内のすべてのコントロールとコントロールをオフに処分するが、顕著なメモリリークが依然として存在します。

Formクラス

public partial class formClass 
{ 
    //Initialize a bunch of managed resources to null 
    someOtherForm form2; 
    someOtherForm form3; 
    //connect some events on child forms to buttons on this form object 
    this.form2.cancelButtonClicked += someFunction; 
    this.form3.cancelButtonClicked += someFunction; 
    // Form closed Event 
    private void formClass_FormClosed(object sender, FormClosedEventArgs e) 
    { 
     //set form2 and form3 visibility to false 
     // clear AND dispose all controls of form2 
     // clear AND dispose all controls of form3 
     //set form2 and form3 to null 
     // clear AND dispose off all controls of formClass 
     // Dispose this (formClass) object 
    } 
} 

私はフォームオブジェクトを初期化した方法で可能な問題がありますか?それらは処分されないのですか?

+3

あなたはメモリリークがあることだと思いますなぜ?ガベージコレクションは、メモリを実際に解放するときにはそれ自身で決定することに注意してください。これは必ずしも即座に起こるとは限りませんが、gcが次の割り振り要求を満たすのに十分なメモリーがないことに気づいたときに最終的に実行できます。 btw:フォームを破棄すると、すべてのコントロール自体が破棄されます。手動で行う必要はありません。 –

+0

メモリリークがあると考えられる原因は何ですか? – tonythewest

+1

タイマーとフォームオブジェクトを処分しようとしていますか? –

答えて

1

はこちらをご覧ください:前本当に子供が処分されたメモリを形成して持って処分にイベントハンドラ(_show)を除去するMemory Leaks in Winforms application

てみてください。

+0

愚かな質問であるかもしれないことを私に許可してください...イベントはどのようにして_showがformClassのオブジェクトに影響しますか?これはsomeClassのイベント(フォームではありません)です。これは、タイマー内で条件が満たされたときに通知されます。また、このイベント、_showを取り除くと、後でタイマー信号はどうなりますか? – user1173240

+0

@ user1173240あなたの応答の中に 'form.someFunction'メソッドがありませんが、問題を適切に検出するために' formClass'オブジェクト全体を見る必要があるとは確信していません。フォームを破棄または閉じても、UI要素は削除されません。 'formClass'に変数、オブジェクト、イベントハンドラなどがある場合は、それ自身のすべてのオブジェクトに対して' .Dispose() 'というフォーム呼び出しの' FormClosed'イベントを持たせる必要があります。それは自分のためのすべてのコードを見ることなく私の最高の推測です。 –

+0

私はformClass formClosedイベントで行っていることを本質的に記述したコードをいくつか追加しました。 – user1173240

0

イベントハンドラを削除していないため、リークの原因となる可能性があります。 someClass使い捨てを作成し、Disposeメソッドでハンドラを削除する必要があります。

どのようにリークがあることを確認していますか?ガベージコレクタは遅れて実行され、メモリが収集されていないと感じます。あなたは明示的に各フォームの廃棄後ギガバイトを呼び出し、何が起こるかを見ることができます。

formClassObject.Dispose(); 

GC.Collect(); 
GC.WaitForPendingFinalizers(); 
GC.Collect(); 
GC.WaitForPendingFinalizers(); 

他のいくつかのヒント:

あなたが例外をスローし、適切に配置されていない可能性が作成フォーム。 あなたがモーダルダイアログ(ShowDialogをを呼び出す)を作成するので、あなたは用いたパターン使用する必要があります:あなたは.NETのプロファイラを使用して、リークのトラブルシューティングを行うことができ

using (formClass formClassObject = new formClass()) 
{ 
    formClassObject.someFunction(); 
} 

を。

は代替のためのこの記事を参照してください。

What Are Some Good .NET Profilers?

+0

私は新しいフォームを作成し、コントロールを初期化するイベントを発生するたびにメモリが著しく増加するため、リークがあると思います。これとは別に、アプリケーションのタスク管理のユーザーオブジェクトカウンタが上がります。私が10のフォームを開くと、メモリがかなり増えますので、User Objectsを実行してください。アプリケーションを実行している間も、フォームをすべて閉じてもどちらも表示されません。ユーザーオブジェクトのカウントは少し下がりますが、高いままです。私はUIのデータソースに問題があると思っていたが、すべてのオブジェクトとコントロールが管理されているため、フォームクロージャーを使用しないでください。 – user1173240

+0

意味があります。可能であれば、.NETプロファイラの問題を解決したり、フォームクラスをできるだけ軽くしたり(可能であれば)します。大量のメモリリークが検出された場合、通常、それは適切に処理されていないデータソースです(すでに疑うように)。 – GeorgeT

関連する問題