【问题标题】:How can I find out how much of address space the application is consuming and report this to user?如何找出应用程序占用了多少地址空间并将其报告给用户?
【发布时间】:2010-09-10 14:16:42
【问题描述】:

我正在为一个应用程序编写内存管理器,作为一个由二十多名编码人员组成的团队的一员。我们的内存配额用完了,我们需要能够看到发生了什么,因为我们似乎只使用了大约 700Mb。我需要能够报告它的去向——碎片化等。有什么想法吗?

【问题讨论】:

    标签: winapi memory memory-management memory-dump


    【解决方案1】:

    您可以为此使用现有的内存调试工具,我发现 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);
    }
    

    【讨论】:

    • 您似乎错过了 MemoryValidator 的链接,因为您可能不想明确指出该名称的很多工具
    【解决方案2】:

    您还可以从 Tool Help API 中找到有关 Heap32ListFirst/Heap32ListNext 进程中堆的信息,以及有关使用 Module32First/Module32Next 加载的模块的信息。

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

    【讨论】:

      【解决方案3】:

      我们的(巨大的)应用程序(一个 Win32 游戏)最近开始抛出“配额不足”异常,我负责找出所有内存的去向。这不是一项简单的工作——这个问题和this one 是我第一次尝试找出答案。堆行为是出乎意料的,准确跟踪您使用了多少配额以及有多少可用配额迄今为止被证明是不可能的。事实上,无论如何,它并不是特别有用的信息——“配额”和“放东西的地方”是微妙而令人讨厌的不同概念。尽管枚举堆和模块也很方便,但公认的答案是最好的。我使用来自 MS 的 DebugDiag 来查看情况的真正可怕之处,并了解真正彻底跟踪所有事情是多么困难。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-08-10
        相关资源
        最近更新 更多