【发布时间】:2016-04-21 17:27:59
【问题描述】:
我正在使用 ASP.NET 4.5 (C# / WebForms) 在 SQL Server 数据存储之上构建管理站点,这需要我检索大型记录集(250K+ 记录)。在开发过程中,在 IIS Express 上,我一直收到源自 IIS 的 Out Of Memory (OOM) 异常。我可以查看任务管理器并观察内存使用量从 120,000K 飙升到 600,000K 以上。
我遇到的问题(其他问题)是,当我返回并过滤查询以使其不返回尽可能多的记录时,我继续收到 OOM 异常,因为 IIS 没有从上一个查询中释放内存.新查询所需的内存只是堆积在已分配的内存之上。
在完整的 IIS 7 安装中(仍然在我的 DEV 机器上)我没有从 IIS 获得初始 OOM 异常,但是它仍然没有释放内存,这将继续导致问题随着内存继续堆积,未来的 IIS 活动。我知道 GC 最终应该会清理它,但我需要它立即发生。
所以问题是如何按需从 IIS 中释放未使用但已分配的内存?
我找到了以下 SF 文章...
这导致我尝试以下...
protected override void OnPreRender(EventArgs e)
{
try
{
var data = this.GetSessionList();
BindUI(data);
}
catch (Exception ex)
{
//
// display error message
while (ex.InnerException != null) { ex = ex.InnerException; }
String msg = (ex.GetType() == typeof(OutOfMemoryException)) ? MessagesConfigService.OutOfMemory.SessionReports : ex.Message;
ucAlert.ShowMessage(msg, ucAlertMessage.AlertStates.DANGER);
}
finally
{
//
// Clean up anything being held on to in memory. This will not prevent OOM
// exceptions for too-large queries, but will prevent further OOM errors for
// smaller queries that follow.
GC.Collect();
Int64 totalMemory = GC.GetTotalMemory(true);
}
base.OnPreRender(e);
}
在 finally 子句中,我分别尝试了每种 GC 方法以及同时尝试了每种 GC 方法,但没有发现 IIS 占用的内存有所减少。
我最初没有想到的另一件事,但是当我输入这个时,意识到很重要......我需要清除内存但保留会话状态......所以无论解决方案是什么,它都不能消除会话状态,这将导致用户必须重新登录。
那么……有什么想法吗?
提前谢谢你:)
-G
附:如此大的记录集的原因是因为企业希望能够将数据导出到 Excel 电子表格中,因此对结果进行简单的分页不一定是一种选择。此外,查询执行时会有相当长的延迟,因此必须忍受每个页面的执行时间是令人望而却步的。我对此查询的性能调整有疑问,但显然超出了此问题的范围。
【问题讨论】:
-
你可以阅读这篇文章。 stackoverflow.com/questions/9666356/…
-
如果没有剩余引用,将释放内存。这表明存在错误或误解。此外,OOM 并非源自 IIS。当您用尽可用内存时,它来自 CLR。发布更多代码并切换到 64 位。
标签: c# asp.net iis memory memory-management