使用Visual Studio确定堆栈空间

我在Visual Studio 2005中用C编程.我有一个多线程程序,但这在这里并不是特别重要.

如何确定(大约)我的线程使用多少堆栈空间?

我计划使用的技术是将堆栈内存设置为某个预定值,比如0xDEADBEEF,运行程序很长时间,暂停程序,并调查堆栈.

如何使用Visual Studio读取和写入堆栈内存?

编辑:例如,参见“How to determine maximum stack usage.”这个问题谈到嵌入式系统,但在这里我试图在普通PC上确定答案.

Windows不会立即提交堆栈内存;相反,它为它保留地址空间,并在访问时逐页提交.阅读 this page以获取更多信息.

因此,堆栈地址空间由三个连续区域组成:

>保留但未提交的内存,可用于堆栈增长(但从未访问过);
> Guard页面,它从未被访问过,用于在访问时触发堆栈增长;
>提交的内存,即线程访问过的堆栈内存.

这允许我们构造一个获取堆栈大小的函数(具有页面大小粒度):

static size_t GetStackUsage()
{
    MEMORY_BASIC_INFORMATION mbi;
    VirtualQuery(&mbi, &mbi, sizeof(mbi));
    // now mbi.AllocationBase = reserved stack memory base address

    VirtualQuery(mbi.AllocationBase, &mbi, sizeof(mbi));
    // now (mbi.BaseAddress, mbi.RegionSize) describe reserved (uncommitted) portion of the stack
    // skip it

    VirtualQuery((char*)mbi.BaseAddress + mbi.RegionSize, &mbi, sizeof(mbi));
    // now (mbi.BaseAddress, mbi.RegionSize) describe the guard page
    // skip it

    VirtualQuery((char*)mbi.BaseAddress + mbi.RegionSize, &mbi, sizeof(mbi));
    // now (mbi.BaseAddress, mbi.RegionSize) describe the committed (i.e. accessed) portion of the stack

    return mbi.RegionSize;
}

需要考虑的一件事:CreateThread允许指定初始堆栈提交大小(通过dwStackSize参数,当未设置STACK_SIZE_PARAM_IS_A_RESERVATION标志时).如果此参数非零,则仅当堆栈使用量大于dwStackSize值时,我们的函数才会返回正确的值.

相关文章
相关标签/搜索