ASP.net MVC - Razor HTML Helper 正在抢占内存而不放手
ASP.net MVC - Razor HTML Helper is grabbing memory and not letting go
我有一个全新的 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";
}
列表页面包含 table 300 行,每行显示 class 的 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>
如您所见,table 中的单元格的样式基于 Razor HTML Helper 的结果,如下所示:
@helper DetermineStrikethruStyle(bool isStrikeThru)
{
@(isStrikeThru ? "text-decoration: line-through;" : "")
}
问题
下面可以看到每次刷新列表页面时内存是如何被消耗的。
启动时 – 显示主页
刷新索引页后 x 10
第一次显示列表页面后
第二次显示列表页面后
第3次显示列表页后
第4次显示列表页后
第5次显示列表页面后
避免问题
只需删除列表页面中对 Razor HTML Helper 的调用即可完全避免该问题。
@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
第一次显示列表页面后
…第5次后
…第25次后
…第50次后
有什么想法吗?
我现在很困惑,结果是一个无法使用的应用程序。
任何人都可以提供任何指导吗?
我认为当你这样做时它正在递归 return View(homeViewModel);
尝试 return 默认视图的 View() 并查看问题是否仍然存在。
移动
@helper DetermineStrikethruStyle(bool isStrikeThru)
{
@(isStrikeThru ? "text-decoration: line-through;" : "")
}
在服务器端的 HtmlHelper 扩展方法上。
public static string DetermineStrikethruStyle(this HtmlHelper helper, bool isStrikeThru)
{
return isStrikeThru ? "text-decoration: line-through;" : String.Empty;
}
我有一个全新的 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";
}
列表页面包含 table 300 行,每行显示 class 的 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>
如您所见,table 中的单元格的样式基于 Razor HTML Helper 的结果,如下所示:
@helper DetermineStrikethruStyle(bool isStrikeThru)
{
@(isStrikeThru ? "text-decoration: line-through;" : "")
}
问题
下面可以看到每次刷新列表页面时内存是如何被消耗的。
启动时 – 显示主页
刷新索引页后 x 10
第一次显示列表页面后
第二次显示列表页面后
第3次显示列表页后
第4次显示列表页后
第5次显示列表页面后
避免问题
只需删除列表页面中对 Razor HTML Helper 的调用即可完全避免该问题。
@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
第一次显示列表页面后
…第5次后
…第25次后
…第50次后
有什么想法吗? 我现在很困惑,结果是一个无法使用的应用程序。
任何人都可以提供任何指导吗?
我认为当你这样做时它正在递归 return View(homeViewModel);
尝试 return 默认视图的 View() 并查看问题是否仍然存在。
移动
@helper DetermineStrikethruStyle(bool isStrikeThru)
{
@(isStrikeThru ? "text-decoration: line-through;" : "")
}
在服务器端的 HtmlHelper 扩展方法上。
public static string DetermineStrikethruStyle(this HtmlHelper helper, bool isStrikeThru)
{
return isStrikeThru ? "text-decoration: line-through;" : String.Empty;
}