4

Windows Phone (8) アプリを作成しています。2 つの XAML ページがあります。以下を手動でテストした場合:

1. From 1st page, go to 2nd page
2. Press the physical Back button.
3. Go to #1.

最終的に (約 15 回前後に切り替えた後)、アプリがメモリ不足になり、クラッシュします。ページ 1 とページ 2 のデストラクタにデバッグ ステートメントを入れましたが、呼び出されていないようです。

この問題が発生しないようにするにはどうすればよいですか?

4

1 に答える 1

4

I c# 一般に、オブジェクトは GC が望むときに破棄されるため、強制的に破棄する方法はありません。怠け者ですが、あなたのメモリが不足することは許しません。したがって、破棄されると予想されるオブジェクトは、収集する準備ができていません。準備ができていないということは、アプリケーションのどこかにこのオブジェクトへの参照があることを意味します。これらの参照の一部は、プロセス全体に存在するクラス内のフィールドとして明らかですが、他の参照はこれを考慮して見つけるのが困難です。

class LongLivingClass // say main window or some other
                      // instance that lives considerably longer then the other
{
     public event Action SomeEvent;
}


class ShortLivingClass // class that is created and should be destroyed 
                       // many times throughout life of LongLivingClass 
{

     ShortLivingClass(LongLivingClass llc)
     {
             llc.SomeEvent += DoSomething;
     }

     void DoSomething(){/*.../*}
}

それShortLivingClassまでに公開されたイベントにアタッチするLongLivingClassと、dispose メソッドでこのハンドラーを削除しない限り、破棄されません。

 void Dispose()
 {
     llc.SomeEvent -= DoSomething;
 }

IDisposableインターフェイスは、デストラクタのようなランタイムによって強制されないパターンの一部であることに注意してください。呼び出す場所と時間を決定する必要があります。

また、変数をキャプチャするクロージャにも注意してください。それらの変数がインスタンス フィールドである場合は、インスタンスもキャプチャされます。

長期的には、Web で C# のメモリ リークを検索する必要があります。SO では、この幸運を考えると多くの質問があります。

于 2012-12-19T06:43:47.243 に答える