【问题标题】:Can CreateThread interfere with VirtualAlloc usage?CreateThread 会干扰 VirtualAlloc 的使用吗?
【发布时间】:2012-08-08 07:47:33
【问题描述】:

CreateThread分配的栈空间会不会干扰VirtualAlloc的使用?我找不到任何讨论或文档准确解释允许分配堆栈空间的位置...

以下更准确地说明了我的问题:

uint8_t *baseA = (uint8_t*)VirtualAlloc(NULL,1,MEM_RESERVE,PAGE_NOACCESS);

// Create a thread with the default stack size
HANDLE hThread = CreateThread(NULL,0,SomeThreadProc,NULL,NULL,NULL);

// Possibly create even more threads here.

// Can this ever fail in the absence of other allocators? It doesn't here...
uint8_t *baseB = (uint8_t*)VirtualAlloc(NULL,1,MEM_RESERVE,PAGE_NOACCESS);

// Furthermore, in this test, baseB-baseA == 65536 (unless the debugger did something),
// so nothing appeared between baseA and baseB... not even enough space for the
// full 64kb of wastage, as baseA points to 4096 bytes by itself

如果它确实实际上使用了VirtualAlloc 的一些类似物,有没有办法改变Windows 在给定进程中分配堆栈空间的方式?

【问题讨论】:

    标签: c++ winapi virtual-memory


    【解决方案1】:

    堆栈空间可以分配在进程地址空间的任何位置。目前还没有这方面的文档,将来也不太可能出现此类文档。

    您可以放心地假设线程和虚拟分配的创建是独立的。如果不是这样,很多东西都会被破坏。分配器不能给出重叠的地址范围。这是不可想象的。问题出在其他地方。

    唯一可能看起来像相关的东西 - 使用的内存量和虚拟地址空间碎片。在这种情况下,最新的请求将失败。

    我从事内存分析实用程序。

    这张图显示了每个分配大小的虚拟分配数量的分布。

    这是 32 位进程的地址空间内容示例(蓝色 - 已提交,洋红色 - 保留,绿色是空闲内存)。

    我在这里写的都是真实的经历。

    【讨论】:

    • +1 for 'This is unthinkable' - 操作系统会在启动时快速崩溃,甚至可能没有时间蓝屏。
    • 感谢您的回答。也许“干涉”对于这个问题来说是一个严厉的词。我要问的是,基本上,如果CreateThread 可以在任何地方分配堆栈空间——你回答了这个问题。通过“干扰”,我是在问它是否可以分割进程的虚拟地址空间(但是,现在我考虑一下,它还能在哪里分配它?)。因此,看起来随机线程分配会导致没有自定义分配器可以解决的碎片。
    • 我喜欢我自己介绍的“AddrSpaceUtilization”这个概念。这是所有VirtualAlloc 分配的大小总和与地址空间本身大小的比率。我在 Windows 上使用 32 位进程的经验表明,当这个值小于 85-90% 时,一切工作或多或少都正常。当超过90%时,各种问题开始出现。
    【解决方案2】:

    Windows NT 内核以高中断优先级处理内存分配操作,也是线程安全的方式。

    这意味着一个进程中只有一个线程可以同时分配内存,这使得所有分配进程都是线程安全的(理论上)。 堆栈分配和虚拟分配之间不应该有任何干扰。

    另外你应该记住,你可以分配 1GB 的空间,但你的程序仍然只使用它的 2mb RAM。

    那是因为windows“预分配”了虚拟空间,但直到你使用它才分配它(写在上面)。

    实际上,内存管理要复杂得多,但现在您可以放心,任何分配操作都不会干扰,因为 Windows 将您的进程锁定在一个核心上,延迟所有其他线程的分配请求,只要分配得到处理. (死锁)

    *编辑:这也意味着如果您分配数百万个小位,分配和取消分配是一个需要性能的过程。由于这种死锁行为,分配/取消分配更大的内存区域总是更好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-11
      • 2017-09-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多