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

Tim*_*man 7 .net asp.net memory-management c#-4.0

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

ANTS Memory Profiler和PerfMon都显示我的Gen 0堆在Application_Start期间迅速增长到大约1 GB.我在这里读到,Gen 0 Heap的PerfMon计数器实际上显示了Gen 0的"预算",而不是大小(我认为并非所有内存都是进程私有工作集的一部分?).但是蚂蚁探查器显示大约700 MB"分配给.NET未使用的内存",而这似乎是私人工作集的过程中(如报告taskmgr)的一部分.我猜这个大量未使用的内存与大的Gen 0堆有关.

在发生这种情况时,Application_Start中发生的事情是我在一个while循环中读取来自SqlDataReader的大约一百万行.这些用于填充大型缓存以供以后使用.鉴于此,大量未使用内存的明显罪魁祸首是大对象堆碎片,但我不认为是这种情况,因为我预先分配的数量超过了我的大型缓存对象所需的数量.可以肯定的是,我甚至尝试将实际添加到缓存对象的循环部分注释掉; 它没有分配未使用的内存量.

作为测试,我经常尝试在循环期间强制收集gen 0的垃圾回收(针对所有建议,我知道),这导致gen0堆的大小保持在128 MB左右并且还导致仅几MB未使用免费记忆.但它也最大化了我的CPU并使Application_Start占用太长时间.

我的问题是:

1)什么可以导致Gen 0堆的报告大小增长如此之大?

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

3)如果是这样,我该怎么做才能修复它?如果我无法阻止进程在Application_Start期间使用那么多内存,我想至少能够在应用程序启动完成时让它放弃内存.

Chr*_*ain 3

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

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