【问题标题】:ASP.NET WebApp Performance issues: How to resolve?ASP.NET WebApp 性能问题:如何解决?
【发布时间】:2011-08-22 04:21:49
【问题描述】:

我一直在尝试找出我们的 ASP.NET Web 应用程序的一些性能问题。这是一个在线应用程序,由多个用户(10+)使用。只是一个快速的概述:应用程序使用 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);
    }

    ............................
 }

【问题讨论】:

  • 什么是 DataManager?你也可以显示那个的代码吗?
  • DataManager 是一个密封的静态类,包含常用的数据库方法和包装器,如上面的 execute 方法,它是 cmd.ExecuteNonQuery() 的简单包装器;

标签: c# asp.net performance memory-leaks red-gate-ants


【解决方案1】:

嗯.. 我看到事件处理程序“已删除”是一个公共事件处理程序。所以我的猜测是首先创建 Rule 对象,然后为 Rule.deleted 分配一个事件处理程序。如果是这种情况,那么正如您所怀疑的那样,事件处理程序可能是 Rule 对象未被垃圾收集的原因。

编辑:

也许你可以试试这样的:

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;
    }
}

【讨论】:

  • 我更新了帖子。该事件被分配在另一个名为 Option 的类中。我只是不确定何时以及如何取消注册该活动。
  • 是的,我也是这么想的。我是否需要随时显式调用规则对象的 dispose 方法,或者我需要做的就是以上这些?我还实现了 Finalize 方法,该方法调用 dispose 方法,以防对象没有被释放或者对它的引用丢失。
  • 您可能不需要在 Rule 类中做任何事情 - 原因是对 Rule 类的引用造成了问题,此时我们怀疑 Option 是罪魁祸首。 Finalize 可能会有所帮助,实际上,您可以重构它以在 Options 本身的 Finalize 中取消注册事件,而不是处置。那么,在这之后你看到有什么不同吗?还是我们找错了树?
猜你喜欢
  • 2016-02-13
  • 2021-06-12
  • 1970-01-01
  • 2011-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多