我一直在努力识别ASP.NET Web应用程序的一些性能问题。它是一个在线应用程序,由多个用户(10+)使用。简单概述:applcation使用Web表单,MVC页面,Web服务等组合......当多个用户连接到应用程序时,它似乎变得非常慢。在调查内存之后,似乎应用程序正在使用大量内存并且正在减慢计算机速度,这表明未处理的非托管资源。我安装了ANTS,然后在系统上捕获了一些应用程序。事实证明,非托管资源使用了大量内存:http://tinypic.com/r/154ujra/7
这是我第一次分析内存。 ANTS探查器指示我的一个类(RULE)具有大量活动实例: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);
}
............................
}
答案 0 :(得分:1)
嗯......我看到eventhandler'已删除'是公开的。所以我的猜测是首先创建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;
}
}