我正在为一个应用程序编写内存管理器,作为二十多个编码器团队的一部分。 我们的内存配额用完了,我们需要能够看到发生了什么,因为我们似乎只使用了大约700Mb。 我需要能够报告一切进展-碎片等等。有什么想法吗?
您可以为此使用现有的内存调试工具,我发现Memory Validator 1非常有用,它可以跟踪API级别(堆,新...)和OS级别(虚拟内存)分配并显示虚拟内存映射。
我还发现非常有用的另一个选项是能够基于VirtualQuery函数转储整个虚拟空间的地图。我的代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| 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,它提供的功能与工具帮助部分(但不完全)重叠。
我们的(巨大的)应用程序(一个Win32游戏)最近开始引发"配额不足"异常,我负责找出所有内存的去向。这不是一件微不足道的工作-这个问题和这个问题是我第一次尝试找出答案。堆行为是意外的,到目前为止,准确跟踪已使用的配额和可用的配额是不可能的。实际上,它并不是特别有用的信息-" quota"和"放在某处的东西"是微妙而令人讨厌的不同概念。尽管枚举堆和模块也很方便,但可接受的答案就可以了。我使用了来自MS的DebugDiag来查看这种情况的真正恐怖之处,并了解真正全面跟踪所有内容的难度。