我使用 C# 编写了一个 Hello-world 控制台应用程序
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World");
Console.Read();
}
}
,当我启动它时,它占用的内存是:
然后,我尝试创建这个过程的转储文件:
创建dump后,该进程占用的内存为:
您可以看到工作集大小发生了巨大变化,这让我感到惊讶。
关于这个内存增量还有一些有趣的事情是:
- 在我的进程内存工作集增加到 46 MB 之后,它似乎不再减少到 7 MB。
- 转储文件的大小不是 7MB,而是 46MB。
- 私有(private)工作集从 1.83MB 增加到 2.29MB
然后,这是我的问题:
1.为什么随着create dump操作会出现内存增量?
2.过去,当测试人员报告内存泄漏问题并向我发送转储文件时,我将转储文件大小视为目标进程在实验室环境中占用的内存大小。但是从上面这个简单的例子来看,好像我总是错的?
3.我 super 好奇这个46MB的转储文件里面有什么(换句话说,我 super 好奇为什么当前的hello world应用占用了46MB内存)。我熟悉 SOS 命令,如 !DumpHeap 或 !eeheap,但这些命令不足以说明 46MB 大小文件中的所有内容。谁能分享一些有用的工具、链接或说明?
非常感谢您的帮助!
最佳答案
在 95% 的情况下(甚至更多,我没有这方面的统计数据),您不必担心工作集。微软选择工作集列作为任务管理器的默认列是相当具有误导性的。
应用程序需要的内存称为虚拟内存。您可以区分三种不同类型的虚拟内存:
- 预留内存,既不存在于 RAM 中,也不存在于磁盘中
- 提交的内存,目前不需要,因此写入磁盘
- 提交的内存,这是当前需要的,因此在 RAM 中可供 CPU 访问。这称为工作集。
Windows 减少或增加工作集的原因有很多。在许多情况下,可以在您的应用程序以外的其他应用程序中找到原因。但是,在您描述的情况下,这是很明显的:
- 调试器挂起进程
- 调试器创建一个新线程并触发 MiniDumpWriteDump功能
- 该函数需要读取所有提交的内存以便将其写入转储
- 当访问虚拟内存时,那些已经被分页到磁盘的内存部分需要被分页回RAM。
- 我们之前了解到,RAM中的虚拟内存称为Working Set,所以Working Set增加
但是,这仍然取决于您在创建转储时对 PC 进行的其他操作。尝试运行一个多线程应用程序,该应用程序在转储进程时会大量使用内存。您可能会发现 Windows 会考虑这种情况,并且在内存分页之前,它会调出您自己进程的内存。在这种情况下,工作集不会像您的屏幕截图中那样增加。
所以,再说一次:不要担心工作集。 Windows 只是认为它有足够的剩余 RAM 来加速转储创建过程。它很可能使用了原本未使用的内存,或者减少了用于磁盘缓存的 RAM 量。
如果您想查看 RAM 内容,请尝试 SysInternals RAMMap .在不同情况下重复创建转储,例如在复制文件或进行内存密集型计算时。
关于memory - 为什么创建转储文件操作会极大地增加工作集(内存)的大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25931385/