C++ 线程第一次创建时消耗多少内存?

C++ 线程第一次创建时消耗多少内存?,c++,multithreading,winapi,C++,Multithreading,Winapi,我知道在一个应用程序中创建太多线程并不是其他运行进程的“好邻居”,因为即使这些线程处于有效休眠状态,cpu和内存资源也会被消耗 我感兴趣的是:睡眠线程消耗了多少内存(win32平台)? 理论上,我假设在1mb的范围内(因为这是默认的堆栈大小),但我很确定它小于这个,但我不确定为什么 在此方面的任何帮助都将不胜感激 (我问的原因是我正在考虑引入一个线程池,我想了解创建一个由5个线程组成的线程池可以节省多少内存,而手动创建的线程池只有20个)我想你很难检测到对工作代码进行这种更改会产生什么影响-从2

我知道在一个应用程序中创建太多线程并不是其他运行进程的“好邻居”,因为即使这些线程处于有效休眠状态,cpu和内存资源也会被消耗

我感兴趣的是:睡眠线程消耗了多少内存(win32平台)?

理论上,我假设在1mb的范围内(因为这是默认的堆栈大小),但我很确定它小于这个,但我不确定为什么

在此方面的任何帮助都将不胜感激


(我问的原因是我正在考虑引入一个线程池,我想了解创建一个由5个线程组成的线程池可以节省多少内存,而手动创建的线程池只有20个)

我想你很难检测到对工作代码进行这种更改会产生什么影响-从20个线程减少到5个线程。然后增加管理线程池的复杂性(和开销)。也许在嵌入式系统上值得考虑,但是Win32


您可以将堆栈大小设置为您想要的任何大小。

这在很大程度上取决于系统:

但通常,每个过程都是独立的。通常,系统调度器确保每个进程都能平等地访问可用的处理器。因此,多线程应用程序时间在可用线程之间多路复用

分配给线程的内存将影响进程可用的内存,但不会影响其他进程可用的内存。一个好的操作系统会将未使用的堆栈空间分页,这样它就不在物理内存中了。不过,如果线程在活动时分配了足够的内存,那么当每个处理器的内存被分页到辅助设备或从辅助设备分页时,可能会导致抖动

我怀疑休眠线程对系统有任何(很少)影响。

  • 它没有使用任何CPU
  • 它使用的任何内存都可以调出到辅助设备

我有一个线程使用量很大的服务器应用程序,它使用由客户设置的可配置线程池,在至少一个站点中,它有1000多个线程,启动时只使用50 MB。原因是Windows为堆栈保留了1MB(它映射了其地址空间),但不一定在物理内存中分配,只分配了其中的一小部分。如果堆栈增长超过该值,则会生成页面错误并分配更多物理内存。我不知道初始分配是什么,但我假设它等于系统的页面粒度(通常为64KB)。当然,线程在创建时也会为其他事情(TLS、TSS等)使用更多的内存,但我估计总内存大约为200KB。请记住,任何不经常使用的内存都会被虚拟内存管理器卸载。

如果您使用的是Vista或Win2k8,只需使用本机Win32线程池API即可。让它算出尺寸。我还将考虑将工作负载类型如CPU密集型磁盘与磁盘I/O划分成不同的池。 MSDN线程池API文档


我想这很容易测量

  • 在创建线程之前获取系统使用的资源量
  • 使用默认系统值(默认堆大小和其他值)创建线程
  • 获取创建线程后的资源量,并进行调整(步骤1)
  • 请注意,某些线程需要指定与默认线程不同的值

    您可以尝试通过创建不同数量的线程来找到平均内存使用量(步骤2)

    创建线程时操作系统分配的内存由线程本地数据组成:


    From:“线程不拥有资源,除了堆栈、寄存器副本(包括程序计数器)和线程本地存储(如果有)。”

    添加到Fabios注释:

    记忆是你的第二个顾虑,而不是第一个。线程池的用途通常是限制希望并发运行的线程之间的上下文切换开销,理想情况下是限制可用CPU内核的数量

    上下文切换非常昂贵,通常需要几千到10000个以上的CPU周期


    在WinXP(32位)上进行一次小测试,每个线程大约占用15k私有字节(创建了999个线程)。这是初始提交的堆栈大小,加上操作系统管理的任何其他数据。

    Quick potential correction-据我所知,1MB是默认保留堆栈大小的大小。任何一个单堆栈帧都可能比这个小得多。谢谢你——我不知道我写这篇文章时是怎么想的!你的前提是错误的。创建太多线程被认为是一个糟糕的邻居,因为它会创建大量额外的上下文切换和缓存污染,使整个系统变慢。除非您谈论的是荒谬的线程数(数万个),否则在现代系统上,内存消耗可以忽略不计。x86和x64的页面大小为4KB,而对于ia64,页面大小通常为8KB,但可以配置。x86和x64上的分配粒度(从GetSystemInfo()返回)为64 KB。VirtualAlloc()文档似乎说保留受分配粒度的限制,但保留内存块中的页面可以单独提交。此外,Raymond Chen几年前在博客中谈到线程堆栈大小: