首次创建时线程消耗了多少内存?

时间:2008-11-01 22:15:34

标签: c++ multithreading winapi

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

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

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

对此有任何帮助将不胜感激。

我之所以问的原因是我正在考虑引入一个线程池,我想通过创建一个包含5个线程的池来了解我可以节省多少内存,相比之下,手动20个创建线程

6 个答案:

答案 0 :(得分:7)

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

答案 1 :(得分:4)

添加到Fabios评论:

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

上下文切换非常昂贵,经常引用几千到10,000多个CPU周期。

对WinXP(32位)时钟进行一点测试,每个线程大约 15k个字节(创建了999个线程)。这是初始提交的堆栈大小,以及操作系统管理的任何其他数据。

答案 2 :(得分:1)

如果您使用的是Vista或Win2k8,只需使用本机Win32线程池API即可。让它弄清楚尺寸。我还考虑分区工作负载类型,例如CPU密集型与磁盘I / O进入不同的池。

  

MSDN Threadpool API文档

     

http://msdn.microsoft.com/en-us/library/ms686766(VS.85).aspx

答案 3 :(得分:0)

我认为您很难检测到对工作代码进行此类更改的任何影响 - 将20个线程降低到5.然后添加管理线程池的额外复杂性(和开销)。也许值得考虑嵌入式系统,但Win32?

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

答案 4 :(得分:0)

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

但通常,每个过程都是独立的。通常,系统调度程序确保每个进程获得对可用处理器的相同访问权限。因此,多线程应用程序时间在可用线程之间进行多路复用。

分配给线程的内存将影响进程可用的内存,但不会影响其他进程可用的内存。一个好的操作系统会分页出未使用的堆栈空间,因此它不在物理内存中。虽然如果你的线程在现场分配足够的内存,你可能会导致颠簸,因为每个处理器的内存都被分页到辅助设备。

我怀疑睡眠线程对系统有任何(非常小的)影响。

  • 它没有使用任何CPU
  • 它正在使用的任何内存都可以分页到辅助设备。

答案 5 :(得分:-1)

我想这可以很容易地测量。

  1. 在创建线程之前获取系统使用的资源量
  2. 使用默认系统值(默认堆大小等)创建一个线程
  3. 创建线程后获取资源量并与之区别(步骤1)。
  4. 请注意,某些线程需要指定与默认值不同的值。

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

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

    来自wikipedia:“线程不拥有除堆栈之外的资源,包括程序计数器的寄存器副本和线程本地存储(如果有)。”