【问题标题】:ASP.net MVC - Razor HTML Helper is grabbing memory and not letting goASP.net MVC - Razor HTML Helper 正在抢内存而不是放手
【发布时间】:2017-04-26 14:24:26
【问题描述】:

我有一个全新的 ASP.Net MVC 项目正在消耗内存并拒绝释放它,原因我无法理解。

应用程序

该站点只有 2 个页面,均由 HomeController 提供服务。

public class HomeController: Controller
{
    public ActionResult Index()
    {
        GC.Collect();

        return View();
    }

    public ActionResult List()
    {
        GC.Collect();

        var homeViewModel = new HomeViewModel();

        for (int i = 0; i < 300; i++)
        {
            homeViewModel.MyList.Add(new MyClass
            {
                Field1 = "AAAAAAAAAAAAAAAAAAAAAAAAAAA",
                Field2 = "BBBBBBBBBBBBBBBBBBBBBBBBBBB",
                Field3 = "CCCCCCCCCCCCCCCCCCCCCCCCCCC",
                Field4 = "DDDDDDDDDDDDDDDDDDDDDDDDDDD",
                Field5 = "EEEEEEEEEEEEEEEEEEEEEEEEEEE",
                Field6 = "FFFFFFFFFFFFFFFFFFFFFFFFFFF"
            });
        }

        return View(homeViewModel);
    }
}

public class HomeViewModel
{
    public List<MyClass> MyList { get; set; }

    public HomeViewModel()
    {
        MyList = new List<MyClass>();
    }
}

public class MyClass
{
    public string Field1 { get; set; }
    public string Field2 { get; set; }
    public string Field3 { get; set; }
    public string Field4 { get; set; }
    public string Field5 { get; set; }
    public string Field6 { get; set; }
}

您会注意到 Index 和 List 操作都会在每次调用开始时强制进行垃圾回收。

索引页面仅包含共享的 _Layout.cshtml,没有其他内容。

@model WebApplication1.Controllers.HomeViewModel

@{
    ViewBag.Title = "Home Page";
}

列表页面包含一个包含 300 行的表格,每行显示一个类的 6 个字符串属性,旨在演示我的问题。

@model WebApplication1.Controllers.HomeViewModel

@{
    ViewBag.Title = "List Page";
}

<table class="table table-condensed">
    @foreach (var item in Model.MyList)
    {
        <tr>
            <td style="@MyHelpers.DetermineStrikethruStyle(true)">@item.Field1</td>
            <td style="@MyHelpers.DetermineStrikethruStyle(true)">@item.Field2</td>
            <td style="@MyHelpers.DetermineStrikethruStyle(true)">@item.Field3</td>
            <td style="@MyHelpers.DetermineStrikethruStyle(true)">@item.Field4</td>
            <td style="@MyHelpers.DetermineStrikethruStyle(true)">@item.Field5</td>
            <td style="@MyHelpers.DetermineStrikethruStyle(true)">@item.Field6</td>
        </tr>
    }
</table>

如您所见,表格中的单元格的样式基于 Razor HTML Helper 的结果,如下所示:

@helper DetermineStrikethruStyle(bool isStrikeThru)
{
    @(isStrikeThru ? "text-decoration: line-through;" : "")
}

问题

您可以在下面看到每次刷新 List 页面时内存是如何被消耗的。

启动时 - 显示主页

刷新索引页 x 10 后

第一次显示列表页面后

第二次显示列表页面后

第三次显示列表页面后

第四次显示列表页面后

第五次显示列表页面后

避免问题

只需在列表页面中删除对 Razor HTML 帮助程序的调用,就可以完全避免该问题。

@model WebApplication1.Controllers.HomeViewModel

@{
    ViewBag.Title = "List Page";
}

<table class="table table-condensed">
    @foreach (var item in Model.MyList)
    {
        <tr>
            <td>@item.Field1</td>
            <td>@item.Field2</td>
            <td>@item.Field3</td>
            <td>@item.Field4</td>
            <td>@item.Field5</td>
            <td>@item.Field6</td>
        </tr>
    }
</table>

启动时 - 显示主页

刷新索引页 x 10 后

第一次显示列表页面后

…第五次后

……第 25 次之后

…第 50 次后

有什么想法吗? 我现在很困惑,因此有一个无法使用的应用程序。

任何人都可以提供任何指导吗?

【问题讨论】:

  • 假设您已按原样发布代码,而不试图简化它,那么这里实际上并没有任何会导致内存泄漏的东西。您定义 Razor 助手的方式可能会导致消耗的内存超出应有的程度。如果您尝试将此帮助程序添加为 HtmlHelper 扩展,而不是使用 @helper 语法会怎样?
  • 我很想知道为什么助手声明 using 指令会导致任何新答案中的问题。

标签: c# asp.net asp.net-mvc-4 razor razor-2


【解决方案1】:

移动

@helper DetermineStrikethruStyle(bool isStrikeThru)
{
    @(isStrikeThru ? "text-decoration: line-through;" : "")
}

在服务器端的 HtmlHelper Extensions 方法上。

public static string DetermineStrikethruStyle(this HtmlHelper helper, bool isStrikeThru)
{
    return isStrikeThru ? "text-decoration: line-through;" : String.Empty;
}

【讨论】:

  • 这已经成功了。没有更多的内存泄漏!谢谢!但是知道为什么使用 Razor 而不是 HtmlHelper 扩展方法会导致这种情况吗?
  • 我不知道,但可能 HtmlHelper 是在程序集中编译的,而视图上的 razer 助手是动态编译的。
【解决方案2】:

我认为当你做return View(homeViewModel);时它是递归的

尝试返回 View() 以获得默认视图,看看问题是否仍然存在。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-09
    • 2014-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-18
    相关资源
    最近更新 更多