我正在开发一个管理站点,在SQL Server数据存储区上构建使用ASP.NET 4.5(C#/ WebForms),这需要我检索大型记录集(250K +记录)。在开发中,在IIS Express上,我始终收到来自IIS的 Out Of Memory (OOM)异常。我可以查看任务管理器,并观察内存使用量从120,000K增加到超过600,000K。
我遇到的问题(OTHER问题)是当我返回并过滤查询以便它不返回任意数量的记录时,我继续获得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方法,但没有看到IIS所占用的内存减少。
我原本没想过的另一件事,但是当我输入它时,意识到很重要......我需要清除内存但保留会话状态......所以无论解决方案是什么,它都不能消除会话state,这将导致用户必须重新登录。
所以......有什么想法吗?
提前谢谢你:)
-G
P.S。这种大型记录集的原因是因为企业希望能够将数据导出到Excel电子表格中,因此结果的简单分页不一定是一种选择。此外,由于查询执行时存在相当大的延迟,因此必须忍受每个页面的执行时间将是令人望而却步的。我对这个查询的性能调整有疑问,但显然超出了这个问题的范围。