2009-05-12 3 views
7

大きなメモリリーク解析を行っており、寄与要因の1つがイベントの代理人を削除しないことがわかっていますオブジェクトを十分迅速に(または時には永遠に)GCしないようにします。イベントデリゲートが確実に削除されるように静的解析ルール(FXCop)を書く方法に関するアイデア

FXCopにルールを書き込んでデリゲートがハンドラから削除されていることを確認する方法はありますか?

私はちょうどthisを見たことがあります。そのように私は詳細についてはそこに尋ねます。

答えて

2

は[OK]を、実際のチェックを実装する問題の横に(私の意見では、これはpath coverageに非常に類似しており、実用的ではありません) - ここでそれを支配する新しいFxCopのを書くための方法である:

を最初のいくつかで、かつて私を助けた記事:

単純なルールを実装することは大したことではありません。プロジェクトでは、埋め込みリソースとしてRules.xmlファイルが必要です(hereを参照)。あなたはBaseIntrospectionRuleからクラスを派生し、確認するようにコードを追加します() - メソッド:

public override ProblemCollection Check(TypeNode typeNode) 
{ 
    if(type.IsPublic) 
    { 
    Problems.Add(new Problem(...)); 
    } 
    return Problems; 
} 

私は、これはいくつかの時間前でした。私はそれがまだ記述されたように動作することを願っています:)

+0

これは私が探していた答えに最も近いですありがとうございました。しかし、公平に他の答えも真であり、私たちは可能な限り弱い参照を実装しています。 –

0

ハンドラを実装しているオブジェクトが何らかの形でイベントのあるオブジェクトへの参照を持っていると想定するのは安全ですか?そのような場合は、サイクルを別の方法で中断する方法を理解する方がよいでしょう。

ASP.NETページのイベントハンドラを使用して、同じことが起こりました。ハンドラを実装したオブジェクトには、ページへの参照も含まれていました。私たちができる限り多くのリンクを構造的に破壊した後、少数の残しはWeakReferencesに変更されました。これ以上のメモリ問題はありません!

+0

面白い...ありがとう。 –

3

より具体的にする必要があります。一般的なケースでは、サブスクライバは出版社よりも短命であるため、すべてのイベントデリゲートがアンサブスクライブされていることを確認する必要はありません。また、メモリリークは、サブスクライバがパブリッシャより長く存続しているように見える場合にのみ発生するため、GCがパブリッシャオブジェクトを収集しないようにする参照が存在します。

これで、比較的短命であるオブジェクトのイベントを購読すると、最終的にそれから退会することを確認する必要があります。

ヒューリスティックここでは、すべてのローカル変数オブジェクト(現在のコードブロック{}で囲まれている)と明示的に破棄するすべてのオブジェクトを分析します。これらのオブジェクトのすべてのイベントについて、あなたがそれらに登録した回数と退会した回数を数えます。最初の数値が大きい場合は、警告を発します。

もちろん、すべてのケースをカバーしているわけではありませんが、この問題ですべてのケースをカバーできる静的アプローチはないと思います。十分な方法が必要です。

ダイナミック解析とコードレビューの利点については、個別のトピックであり、質問には関係しないため、ここでは触れません。

+0

ありがとうございます。私は詳細な答えを感謝します。私は、私がチェックしたいことにかなり自信があります。私が知りたいのは、実際にFXルールでこれを行う方法に関する情報です。私は、FXアセンブリを使って新しい複雑なルールを書く方法に関するまともな情報を見つけることができないようです。 –

1

すべてのイベントサブスクリプションをWeakReferencesで処理するように強制できますか?私はこれがあなたのプログラムの実際の流れを分析するよりも簡単に実装できるはずだと思っています。

関連する問題