【发布时间】:2014-12-01 12:35:53
【问题描述】:
所以我使用了 HeapWalk 函数的 this 示例将它实现到我的应用程序中。我玩了一下,当我添加时看到了
HANDLE d = HeapAlloc(hHeap, 0, sizeof(int));
int* f = new(d) int;
创建堆后会记录一些新的输出:
Allocated block Data portion begins at: 0X037307E0
Size: 4 bytes
Overhead: 28 bytes
Region index: 0
所以看到这个我想我可以检查Entry.wFlags,看看它是否设置为PROCESS_HEAP_ENTRY_BUSY,以跟踪我在堆上使用了多少分配的内存。所以我有:
HeapLock(heap);
int totalUsedSpace = 0, totalSize = 0, largestFreeSpace = 0, largestCounter = 0;
PROCESS_HEAP_ENTRY entry;
entry.lpData = NULL;
while (HeapWalk(heap, &entry) != FALSE)
{
int entrySize = entry.cbData + entry.cbOverhead;
if ((entry.wFlags & PROCESS_HEAP_ENTRY_BUSY) != 0)
{
// We have allocated memory in this block
totalUsedSpace += entrySize;
largestCounter = 0;
}
else
{
// We do not have allocated memory in this block
largestCounter += entrySize;
if (largestCounter > largestFreeSpace)
{
// Save this value as we've found a bigger space
largestFreeSpace = largestCounter;
}
}
// Keep a track of the total size of this heap
totalSize += entrySize;
}
HeapUnlock(heap);
这在调试模式下似乎可以工作(totalSize 和 totalUsedSpace 是不同的值)。但是,当我在 Release 模式下运行它时,totalUsedSpace 始终为 0。
我在发布模式下使用调试器逐步完成了它,并且对于每个堆,它循环了 3 次,我通过调用 HeapWalk 在 entry.wFlags 中得到以下标志:
1 (PROCESS_HEAP_REGION)
0
2 (PROCESS_HEAP_UNCOMMITTED_RANGE)
然后退出 while 循环,GetLastError() 按预期返回 ERROR_NO_MORE_ITEMS。
从here 我发现0 的标志值是“空闲的已提交块,即未分配或未用作控制结构。”
有谁知道为什么它在发布模式下构建时不能按预期工作?我对计算机如何处理内存没有太多经验,所以我不确定错误可能来自哪里。在 Google 上搜索没有找到任何结果,所以希望这里有人知道。
更新:我自己仍在调查这个问题,如果我使用 vmmap 监控应用程序,我可以看到该进程有 9 个堆,但是当调用 GetProcessHeaps 时,它返回有 22 个堆。此外,没有任何堆句柄返回与GetProcessHeap() 或_get_heap_handle() 的返回值匹配的值。 GetProcessHeaps 似乎没有按预期运行。下面是获取堆列表的代码:
// Count how many heaps there are and allocate enough space for them
DWORD numHeaps = GetProcessHeaps(0, NULL);
HANDLE* handles = new HANDLE[numHeaps];
// Get a handle to known heaps for us to compare against
HANDLE defaultHeap = GetProcessHeap();
HANDLE crtHeap = (HANDLE)_get_heap_handle();
// Get a list of handles to all the heaps
DWORD retVal = GetProcessHeaps(numHeaps, handles);
而retVal与numHeaps的值相同,表示没有错误。
【问题讨论】:
-
你在HeapWalk前后使用HeapLock和HeapUnlock吗?
-
是的,为了简洁起见,我省略了实际
HeapWalk函数周围的代码。我会将它们添加到 sn-p -
您是使用调试器检查变量(包括
totalUsedSpace)还是将它们写入调试器控制台/stdout/文件?因为调试器在检查发布版本时可能会谎报变量内容。 -
正在将值写入文本文件。
-
我自己还在调查这个问题,如果我使用 vmmap 监控应用程序,我可以看到该进程有 9 个堆,但是当调用
GetProcessHeaps时,它返回有 22 个堆。此外,它返回的任何堆句柄都不匹配GetProcessHeap()或_get_heap_handle()的返回值。GetProcessHeaps的行为似乎与预期不符。
标签: c++ memory memory-management heap-memory