【问题标题】:C# dynamic sitemap memory leakC# 动态站点地图内存泄漏
【发布时间】:2012-06-27 18:25:51
【问题描述】:

我的站点地图在 ascx 中有以下内容:

<asp:SiteMapPath id="SiteMapPath1"runat="server" RenderCurrentNodeAsLink="true" />

在我网站的每个页面上都会调用此站点地图控件。

以及后面的用户控制代码:

private void Page_Load(object sender, EventArgs e)
{
    SiteMap.SiteMapResolve += new SiteMapResolveEventHandler(this.ExpandForumPaths);
}
private SiteMapNode ExpandForumPaths(Object sender, SiteMapResolveEventArgs e)
{
    SiteMapNode currentNode = SiteMap.CurrentNode.Clone(true);
    SiteMapNode tempNode = currentNode;

    if (0 != postID)
    {
        tempNode.Url = tempNode.Url + "?PostID=" + postID.ToString();
    }

    if ((null != (tempNode = tempNode.ParentNode)) &&
        (0 != forumID))
    {
        tempNode.Url = tempNode.Url + "?ForumID=" + forumID.ToString();
    }

    if ((null != (tempNode = tempNode.ParentNode)) &&
        (0 != forumGroupID))
    {
        tempNode.Url = tempNode.Url + "?ForumGroupID=" + forumGroupID.ToString();
    }

    return currentNode;
}

问题在于每次加载页面会消耗 1 - 2 mb 的内存,并且没有释放内存。例如,如果我刷新页面 2 mb 添加到 w3wp.exe,它会不断增长。

   SiteMap.SiteMapResolve += new SiteMapResolveEventHandler(this.ExpandForumPaths);

我确实相信上述行会在每次使用我的用户控件时创建一个新的事件处理程序来导致问题。

问题 这种制作动态站点地图的方法失败了。有没有其他方法可以在不消耗内存的情况下做到这一点,还是我做错了什么?

【问题讨论】:

  • 您是否尝试在页面卸载事件上执行SiteMap.SiteMapResolve -= this.ExpandForumPathsSiteMap.SiteMapResolve 是静态的,因此每次页面加载时处理程序都会堆积在那里。
  • @thecoon,抱歉回复晚了,是的,我做了 SiteMap.SiteMapResolve -= this.ExpandForumPaths;但它没有效果,但如果我强制 GC.Collect();在卸载 w3wp.exe 进程时停止消耗内存。
  • @AI25 如果确实如此(强制 GC.Collect() 调用没有内存增长),这意味着没有内存泄漏,而只是进程选择消耗新资源而不是重用现有资源。当操作系统请求清理(导致自动垃圾收集)时,应该返回您的内存。你发现不是这样吗?
  • @JTorres 如果我禁用此站点地图,编译并上传生产环境中的 dll,它不会超过 55 MB,问题是每天 1000 次页面点击量,以及更多正在运行的其他应用程序在服务器上,只有我在服务器上有 1 GB 的可用内存,奇怪的是当进程达到 200 - 300 MB 时,GC 会清理我的缓存,我在这个应用程序中有 2 MB 缓存,我保留了 24 小时,这意味着它只会在 24 小时后过期,因此 GC 正在清理我的缓存,而不是静态站点地图事件处理程序。

标签: c# asp.net c#-4.0 asp.net-4.0 sitemap


【解决方案1】:

http://netpl.blogspot.com/2008/04/sitemapresolve-and-dynamic-site-map.html

根据上面的文章,在每个 Page_Load 上都会添加一个新的 SiteMapResolveEventHandler,因为 SiteMapResolve 是静态的,这似乎是不必要的过度内存分配的一个很好的理由。文章也有解决方法。

【讨论】:

    【解决方案2】:

    您可以将站点地图保存在一个静态缓存中,并且只针对用户存储当前节点 ID。 1-2mb 的 RAM 表明您正在为每个用户(更不用说每个请求)构建站点地图,这似乎有点过头了。

    有点像

    var nodes = Session["ExpandedNodes"] as List<integer>
    AddCurrentPageToExpandedNodes(nodes)
    var siteMapForUser = StaticSiteMap.Apply(nodes)
    

    【讨论】:

      【解决方案3】:

      您是否考虑过使用这行代码删除处理程序

      SiteMap.SiteMapResolve -= this.ExpandForumPaths
      

      【讨论】:

        猜你喜欢
        • 2023-03-25
        • 2023-03-26
        • 1970-01-01
        • 1970-01-01
        • 2012-05-11
        • 2016-12-11
        • 2017-08-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多