c - 使用 Visual Studio 确定堆栈空间

标签 c visual-studio memory memory-management stack

我在 Visual Studio 2005 中使用 C 语言进行编程。我有一个多线程程序,但这在这里并不是特别重要。

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

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

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

编辑:例如,参见 "How to determine maximum stack usage."这个问题是关于嵌入式系统的,但在这里我试图在普通 PC 上确定答案。

最佳答案

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

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

  • 保留但未提交的内存,可用于堆栈增长(但从未访问过);
  • 保护页面,也从未被访问过,在访问时触发堆栈增长;
  • 已提交的内存,即线程曾经访问过的堆栈内存。

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

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 值时,我们的函数才会返回正确的值。

关于c - 使用 Visual Studio 确定堆栈空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1740888/

相关文章:

c - 定义一些东西(1 << 0)

c99 转到过去的初始化

c - 伪造网络通信以在一台计算机上测试客户端/服务器

c# - 内存不足,无法继续执行程序 VisualStudio

c# - 如何: Generate XML file in Visual Studio 'debug' configuration?

java - 回复 : Big XML file

c# - 为什么 HashSet<T> 归因于 MayLeakOnAbort,但 Dictionary<K,V> 没有?

C - 基于变量的 For 循环没有迭代正确的次数

c - 关于内存管理中函数arch_get_unmapped_area的一个问题(linux)

C#:如何在 Visual Studio 中查找对特定类的等于运算符的引用