asp.net - .NET 中的大型 Gen 0 堆,浪费内存?

标签 asp.net .net c#-4.0 memory-management

我有一个使用大量内存的 ASP.NET/C# Web 应用程序。

ANTS Memory Profiler 和 PerfMon 都显示我的 Gen 0 堆在 Application_Start 期间快速增长到大约 1 GB。我读过here Gen 0 堆的 PerfMon 计数器实际上显示的是 Gen 0 的“预算”,而不是大小(我的意思是不是所有内存都是进程的私有(private)工作集的一部分?)。然而,ANTS 分析器确实显示了大约 700 MB 的“分配给 .NET 的未使用内存”,并且这确实似乎是进程的私有(private)工作集的一部分(如 taskmgr 中报告的)。我猜测大量未使用的内存与大型 Gen 0 堆有关。

发生这种情况时,Application_Start 中发生的情况是我处于 while 循环中,从 SqlDataReader 读取大约一百万行。这些被用来填充大型缓存以供以后使用。鉴于此,大量未使用内存的明显罪魁祸首是大型对象堆碎片,但我认为情况并非如此,因为我预分配的内存超出了大型缓存对象所需的内存。可以肯定的是,我什至尝试注释掉实际添加到我的缓存对象的循环部分;它对分配的未使用内存量没有影响。

作为测试,我经常尝试在循环期间强制执行 gen 0 的垃圾回收(我知道这与所有建议都是相反的),这导致 gen0 堆的大小保持在 128 MB 左右,并且还导致只有少数MB 未使用的可用内存。但它也耗尽了我的 CPU 并使 Application_Start 花费了太长的时间。

我的问题是:

1) 什么会导致所报告的 Gen 0 堆大小变得如此之大?

2)这是一个问题吗?特别是,它是否会导致大量未使用的空间分配给 .NET?

3)如果是这样,我应该做什么来解决它?如果我无法阻止进程在 Application_Start 期间使用那么多内存,我希望至少能够让它在应用程序启动完成时放弃内存。

最佳答案

Gen 0 包含“最年轻、最近分配的对象”,并且与 LOH 是分开且不同的。听起来像是您正在分配大量的小对象(与这些缓存条目相关的所有勘误表,听上去是这样),这些对象是无根的(通过频繁的 GC 保持较小的大小来证明)但没有清理干净及时,因为 GC 尚未认为有必要。 GC 根本没有发现需要进行清理。机器有多少内存?我猜你没有寻呼。

我的理解是,当 GC 认为不再需要时(例如,因为该堆空间已经很长时间没有使用),.NET 可以将未使用的堆 block 返回给操作系统。您是否长时间观察该应用程序,看看是否会出现这种情况?如果您不进行分页,我认为这不是问题。

关于asp.net - .NET 中的大型 Gen 0 堆,浪费内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8763899/

相关文章:

asp.net - Azure Application Insights 不显示数据

c# - 检查字符串是否包含字符和数字

c# - 显示一个窗口服务的弹出窗体

javascript - 从 Controller 发送两个参数到 Ajax |网络

asp.net - 我可以在不使用 flash 或 silverlight 的情况下使网站全屏显示吗?

c# - 在 Entity FrameWork 中为多种用途映射相同的模型类

c# - 使用表名访问DataSet中的DataTable

c# - 为什么在 C# 中允许 "long"作为数组长度?

c# - 实现迭代器时,返回 IEnumerator 或 IEnumerable 有什么区别?

c# - 使用 MS Exchange 2007 编程