为什么创建转储文件操作会极大地增加工作集(内存)大小?

Tig*_*ing 2 memory windbg dump

我使用 C# 编写了一个 Hello-world 控制台应用程序

class Program
{
  static void Main(string[] args)
  {
    Console.WriteLine("Hello World");

    Console.Read();
  }
}
Run Code Online (Sandbox Code Playgroud)

,当我启动它时,它占用的内存是: 在此输入图像描述

然后,我尝试创建该进程的转储文件: 在此输入图像描述

创建dump后,该进程占用的内存为: 在此输入图像描述

你可以看到工作集大小发生了很大的变化,这让我感到惊讶。

关于此内存增量的其他有趣之处是:

  1. 当我的进程内存工作集增加到 46 MB 后,似乎它并没有再减少到 7 MB。
  2. 转储文件的大小不是 7MB,而是 46 MB。
  3. 私有工作集从 1.83MB 增加到 2.29MB

而且,这是我的问题:

1.为什么创建转储操作时会出现内存增量?

2.过去,当测试人员报告内存泄漏问题并向我发送转储文件时,我将转储文件大小视为目标进程在实验室环境中占用的内存大小。但从上面的简单例子来看,我似乎总是错的?

3.我非常好奇46MB转储文件里面有什么(换句话说,我非常好奇为什么当前的hello world应用程序占用了46MB内存)。我熟悉 SOS 命令,例如 !DumpHeap 或 !eeheap,但这些命令不足以告诉 46MB 大小的文件内的所有内容。有人可以分享一些有用的工具、链接或说明吗?

非常感谢您的帮助!

Tho*_*ler 5

在 95% 的情况下(甚至更多,我没有这方面的统计数据),你不必担心工作集。微软选择工作集列作为任务管理器的默认列是相当误导的。

应用程序所需的内存称为虚拟内存。您可以区分三种不同类型的虚拟内存:

  1. 保留内存,既不存在于 RAM 也不存在于磁盘上
  2. 提交的内存,当前不需要,因此写入磁盘
  3. 已提交的内存,当前需要该内存,因此可在 RAM 中供 CPU 访问。这称为工作集。

Windows 减少或增加工作集的原因有很多。在许多情况下,可以在您的应用程序之外的其他应用程序中找到原因。然而,在你描述的情况下,这是很明显的:

  1. 调试器暂停进程
  2. 调试器创建一个新线程并触发MiniDumpWriteDump函数
  3. 该函数需要读取所有已提交的内存才能将其写入转储
  4. 当访问虚拟内存时,那些已经被分页到磁盘的内存部分需要被分页回RAM。
  5. 之前我们了解到,RAM中的虚拟内存称为Working Set,因此Working Set增加

但是,这仍然取决于您在创建转储时使用 PC 执行的其他操作。尝试运行一个在转储进程时大量使用内存的多线程应用程序。您可能会发现Windows会考虑这种情况,并且在调入内存之前,它会调出您自己进程的内存。在这种情况下,工作集不会像屏幕截图中那样增加那么多。

所以,再次强调:不要担心工作集。Windows 只是认为它还有足够的 RAM 来加速转储创建过程。它很可能使用了原本未使用的内存,或者减少了用于磁盘缓存的 RAM 量。

如果您想查看 RAM 内容,请尝试SysInternals RAMMap。在不同情况下重复创建转储,例如在复制文件时或在进行占用大量内存的计算时。