C# 为什么所有堆中的字节都比总内存使用量大得多

C# 为什么所有堆中的字节都比总内存使用量大得多,c#,memory-leaks,windbg,C#,Memory Leaks,Windbg,我们有一个C#Windows服务(运行在Windows2008Server+.NETFramework4.6+GCPerf热修复程序上)。运行几天后,所有堆中的字节大小都达到100 GB以上(已提交),私有字节也非常高(110 GB+),但RAM使用率只有68 GB(工作集)和59 GB(私有字节)。此服务器上的页面文件只有10 GB 我做了一个转储并运行WinDbg+SOS来分析内存使用情况,我发现有很多空闲的对象(大约54GB)。这可能是由免费对象引起的吗?这些空闲对象是否只占用虚拟内存而不

我们有一个C#Windows服务(运行在Windows2008Server+.NETFramework4.6+GCPerf热修复程序上)。运行几天后,所有堆中的字节大小都达到100 GB以上(已提交),私有字节也非常高(110 GB+),但RAM使用率只有68 GB(工作集)和59 GB(私有字节)。此服务器上的页面文件只有10 GB


我做了一个转储并运行WinDbg+SOS来分析内存使用情况,我发现有很多
空闲的
对象(大约54GB)。这可能是由
免费
对象引起的吗?这些空闲对象是否只占用虚拟内存而不占用物理内存?如果没有,提交的虚拟内存如何可能比使用的物理内存+页面文件大得多?

您刚刚发现了按需零页面的概念

让我引用Windows Internal第6版第2部分[]第10章中关于内存管理的内容(本书我的版本第276页):

对于其中许多项,提交费用可能表示存储的潜在使用,而不是实际使用。例如,私有提交内存的一页在被引用至少一次之前,实际上不会占用RAM的物理页或等效的页面文件空间。在此之前,它是一个需求量为零的页面[…],但在第一次创建虚拟空间时,提交费用会占用这些页面。这样可以确保在以后引用该页时,实际的物理存储空间将可用于该页

这意味着:当访问(已提交但尚未占用/未使用的)内存时,Windows将增加工作集或页面文件的大小

你的判决

这些空闲对象是否只占用虚拟内存而不占用物理内存


与问题的其余部分不太相符。任何内存,不管它填充了什么(.NET
Free
objects、.NET常规对象,甚至是C++),都可能消耗物理内存(然后它在工作集中)或不消耗物理内存(然后它在页面文件中)。

嗨,托马斯,谢谢你的回复。需求零页面对我来说绝对是一个新概念。现在有一个新的方向。但混乱仍在继续。当我通过运行“.”总结列出的所有主要.net对象时!dumpheap-stat'约为89G(包括54G自由对象)。我认为这些对象是被引用的或用来被引用的,应该已经为它们分配了物理内存吗?@Jason:不一定。NET可能会“认为”你的程序接下来需要更多的RAM,所以它会预先分配40MB的内存。当时,它被分配为需求零。但是,您的程序在单个块中需要50MB的内存(例如,一个字节[])。NET需要分配50MB的新内存以获得物理内存。但是旧的预先分配的40MB仍然作为零需求存在。您可以尝试实现一个示例程序来演示这种行为,或者看看是否可以用我的。尝试在VitualAlloc()上放置(本机)断点。