1

ASP.NET Web アプリケーションのパフォーマンスの問題を特定しようとしています。これは、複数のユーザー (10+) が使用するオンライン アプリケーションです。簡単な概要: このアプリケーションは、Web フォーム、MVC ページ、Web サービスなどを組み合わせて使用​​します。複数のユーザーがアプリに接続すると、非常に遅くなるようです。メモリを調査した後、アプリケーションが大量のメモリを使用しており、それがマシンの速度を低下させているように見えます。これは、管理されていないリソースが破棄されていないことを示しています。ANTS をインストールしてから、システム上のいくつかのアプリケーションをキャプチャしました。多くのメモリが管理されていないリソースによって使用されていることがわかりました: http://tinypic.com/r/154ujra/7

メモリのプロファイリングを行ったのはこれが初めてです。ANTS プロファイラーは、私のクラス (RULE) の 1 つに多数のライブ インスタンスがあることを示しています: http://tinypic.com/r/1264ltu/7 (これは GC によって解放されていないようです)

クラス レベル ( http://tinypic.com/r/2r3v6nq/7 ) にドリルダウンすると、クラスがメモリから解放されていないという警告が表示されます。これは、イベント ハンドラーが登録解除されていないことが原因である可能性があります。そのクラスにはイベント ハンドラーのインスタンスが含まれています。

public class Rule
{
    public event EventHandler deleted;

    public void Delete()
    {
        if (baseQuestionnaire.basePortfolio.mode != Mode.Admin)
        {
            throw new Exception("Rules can only be deleted in Admin mode");
        }
        else
        {
            // Delete the rule from the database
            if (id != -1)
            {
                string delete = "DELETE FROM tb" + DataManager.dbPrefix + "_QuestionRule WHERE QuestionRuleId = " + id.ToString();
                DataManager.execute(delete);
            }

            // Raise a deleted event
            if (deleted != null)
                deleted(this, new EventArgs());
        }
    }
 } 

イベントはこのように別のクラスに割り当てられますが、登録が解除されることはありません

public class Option : IComparable
{

    public void AddRule(Rule newRule)
    {
        newRule.deleted += new EventHandler(newRule_deleted);
        allRules.Add(newRule);
    }

    ............................
 }
4

1 に答える 1

1

うーん..「削除された」イベントハンドラーが公開されていることがわかります。したがって、Rule オブジェクトが最初に作成され、次に Rule.deleted にイベント ハンドラが割り当てられると思います。これが事実である場合、ご想像のとおり、おそらくイベント ハンドラーがルール オブジェクトがガベージ コレクションされない原因です。

編集:

たぶん、次のようなことを試すことができます:

public class Option : IComparable, IDisposable
{

    private Rule newRule;
    private EventHandler newRuleDeletedEventHandler;

    public void AddRule(Rule newRule)
    {
        this.newRule = newRule;
        newRuleDeletedEventHandler = new EventHandler(newRule_deleted);
        newRule.deleted += newRuleDeletedEventHandler;
        allRules.Add(newRule);
    }

    public override void dispose()
    {
        newRule.deleted -= newRuleDeletedEventHandler;
    }
}
于 2011-08-22T04:40:48.937 に答える