1

我有一项服务随着时间的推移间歇性地开始吞噬服务器内存,需要重新启动才能释放它。我用 gflags 转为 +ust,重新启动服务,并开始拍摄预定的 UMDH 快照。当问题再次发生时,资源管理器在工作集和私有字节下报告了多个 GB,但 UMDH 快照仅占进程堆中的几个 MB 分配。

在 UMDH 快照文件的顶部,它提到“仅转储堆管理器收集堆栈的分配”。
当指定 +ust 标志时,进程中的分配怎么会没有痕迹?

如何找出这些 GB 的分配位置/方式?

4

1 回答 1

1

UMDH 是用户模式转储堆的缩写。术语堆在这里是一个关键术语:它仅指 C++ 堆管理。这意味着通过 C++ 堆管理器以外的其他方式分配的所有内存都不会被 UMDH 跟踪。

这可以是

  • 直接调用VirtualAlloc()
  • .NET 使用的内存,因为 .NET 有自己的堆管理器

但即使对于 C++,也存在 C++ 堆管理器无法有效管理大于 512 kB 的分配的情况,因此它只是将其重定向到VirtualAlloc()并且不会创建如此大分配的堆段。

如何找出这些 GB 的分配位置/方式?

对于直接调用VirtualAlloc(),WinDbg 命令!address -summary可能会给出答案。对于.NET,SOS 扩展和!dumpheap -stat可以给出答案。

于 2017-03-21T19:00:24.700 回答