单个Windows线程的内存开销是多少?

6

每个线程的堆栈大小是1 Mb吗?或者这只适用于CLR线程?

我想知道本地Windows线程(c ++)和通过任务管理器查看的CLR线程的内存开销。

谢谢

4个回答

8
默认情况下,nativeCLR 线程的大小均为 1 MB。尽管您可以更改它,但通常这是一个不好的主意。

1
它只保留1MB。直到使用时才会得到物理支持。你为什么说修改它是个坏主意?栈通常可以超出初始保留,如果1MB对于一个简单的线程来说过度了,那么你只是在分割你的地址空间。 - Adrian McCarthy
1
我并没有说这是一个坏主意。我说通常情况下这是一个坏主意。创建大量线程通常是解决问题的错误方法,因此仅为了创建大量线程而减小堆栈大小几乎肯定是一个错误。是的,调整堆栈大小可以在某些情况下产生收益,但这应该只由真正知道自己在做什么的人来完成。另外,我不确定你所说的“堆栈通常可以超出初始保留”。据我所知,没有用于增长堆栈的API。 - Marcelo Cantos
@Adrian 这是一个常见的误解。CLR实际上为每个线程的堆栈分配了1MB的RAM。 - Roman Starkov
@romkyns:你说得对。谢谢你教我新东西。你的链接已经失效了,所以我在MSDN上找到了相关信息。http://msdn.microsoft.com/en-us/library/ms686774%28VS.85%29.aspx - Adrian McCarthy
@Adrian 唉,我发布了那个链接不到1小时网站就挂了 :/ 这里是它的Google缓存版本: CLR提交整个堆栈 - Roman Starkov
@Marcelo Cantos:我说错了。线程的堆栈可以超出初始提交,而不是初始保留。您可以在CreateThread调用中提交少于保留的数量。您也可以通过这种方式覆盖特定线程的默认保留。我也不同意您的“几乎肯定是错误”的结论。 - Adrian McCarthy

4
请参见Mark Russinovich关于win32内核限制的博客,了解单个线程有多大以及使用了多少开销。链接如下:limits
预测.NET线程将使用多少资源可能很难,但我猜测不会太多。

2

内存开销(在RAM中)将是一个内存页面。因此(取决于您的平台),这可能是4KB。

两者的默认堆栈大小均为1MB。但是,这仅是虚拟内存,因此除非使用它,否则不会有RAM开销。


这并不适用于托管代码。CLR总是预先提交托管线程的线程堆栈,因此对于CLR线程,堆栈会计入提交限制。当然,在触及之前,这仍然不是物理内存。 - Stewart
2
这就是我写的(或者说我想写的)。我澄清了答案,以明确它描述的是RAM开销。 - Foxfire

2
根据之前的回答,每个线程的基本开销为1MB。我不会深入探讨各种细微差别 - 其他回答已经涵盖了它们。
对于Microsoft Visual C/C++线程,您还需要考虑每个线程的C运行时工作区的开销,该工作区根据需要分配(并使用Thread Local Storage TlsAlloc()存储),以执行诸如sprintf()、scanf()、strtol()等操作。我没有确切的数据 - 您需要扫描Microsoft CRT的源代码来计算它。
对于其他C/C++运行时(gcc/g++/borland/digital mars),可能会或可能不会存在类似的每个线程数据,这是实现细节。
我们都不知道.Net Execution Engine的内部情况,但那里可能也存储着一些每个线程的数据。不过要弄清楚这个开销可能有些困难。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接