我正在为一个应用程序编写内存管理器,作为二十多名编码员团队的一员。我们的内存配额即将耗尽,我们需要能够了解发生了什么,因为我们似乎只使用了大约 700Mb。我需要能够报告一切的进展情况——碎片等。有任何想法吗?

有帮助吗?

解决方案

您可以使用现有的内存调试工具来实现此目的,我找到了 Memory Validator 1 非常有用,它能够跟踪 API 级别(堆、新...)和操作系统级别(虚拟内存)分配并显示虚拟内存映射。

我也发现非常有用的另一个选项是能够基于 VirtualQuery 函数转储整个虚拟空间的地图。我的代码如下所示:

void PrintVMMap()
{
  size_t start = 0;
  // TODO: make portable - not compatible with /3GB, 64b OS or 64b app
  size_t end = 1U<<31; // map 32b user space only - kernel space not accessible
  SYSTEM_INFO si;
  GetSystemInfo(&si);
  size_t pageSize = si.dwPageSize;
  size_t longestFreeApp = 0;

  int index=0;
  for (size_t addr = start; addr<end; )
  {
    MEMORY_BASIC_INFORMATION buffer;
    SIZE_T retSize = VirtualQuery((void *)addr,&buffer,sizeof(buffer));
    if (retSize==sizeof(buffer) && buffer.RegionSize>0)
    {
      // dump information about this region
      printf(.... some buffer information here ....);
      // track longest feee region - usefull fragmentation indicator
      if (buffer.State&MEM_FREE)
      {
        if (buffer.RegionSize>longestFreeApp) longestFreeApp = buffer.RegionSize;
      }
      addr += buffer.RegionSize;
      index+= buffer.RegionSize/pageSize;
    }
    else
    {
      // always proceed
      addr += pageSize;
      index++;
    }
  }
  printf("Longest free VM region: %d",longestFreeApp);
}

其他提示

您还可以从工具帮助 API 中使用 Heap32ListFirst/Heap32ListNext 查找有关进程中堆的信息,以及使用 Module32First/Module32Next 查找有关已加载模块的信息。

“工具帮助”起源于 Windows 9x。Windows NT 上最初的进程信息 API 是 PSAPI,它提供的功能与 Tool Help 部分(但不完全)重叠。

我们的(巨大的)应用程序(一个 Win32 游戏)最近开始抛出“配额不足”异常,我负责找出所有内存的去向。这不是一项微不足道的工作 - 这个问题和 这个 这是我第一次尝试找出答案。堆行为是出乎意料的,并且到目前为止,准确跟踪已使用的配额量和可用配额量已被证明是不可能的。事实上,无论如何,这都不是特别有用的信息——“配额”和“放置物品的地方”是微妙且令人恼火的不同概念。尽管枚举堆和模块也很方便,但接受的答案已经很好了。我用了 调试诊断 从 MS 中了解情况的真正恐怖,并了解真正彻底追踪一切是多么困难。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top