views:

183

answers:

4

Is it 1 Mb of stack per thread? Or is that just CLR threads?

I want to know the memory over head of native windows threads (c++) and CLR threads as view via Task Manager.

Thanks

+3  A: 

The default is 1 MB for both native and CLR threads. You can alter it, though that's usually a bad idea.

Marcelo Cantos
It only reserves 1MB. It does get physical backing until it's used. Why do you say it's a bad idea to alter it? The stack can usually grow beyond the initial reserve, and if 1MB is overkill for a simple thread, then you're just slicing up your address space.
Adrian McCarthy
I didn't say it's a bad idea. I said that it's _usually_ a bad idea. Creating gazillions of threads is usually the wrong solution to a problem, so reducing the stack size just so you can create gazillions of threads is almost certainly a mistake. Yes, there are circumstances when tweaking the stack size can yield gains, but this should only be done by people who really know what they are doing. Also, I'm not sure what you mean by, "The stack can usually grow beyond the initial reserve". AFAIK, there is no API for growing the stack.
Marcelo Cantos
@Adrian that is a common misconception. [The CLR actually **commits** 1MB of RAM per thread for the stack.](http://www.bluebytesoftware.com/blog/PermaLink,guid,733d7537-f982-4886-af62-66bed0f97ab5.aspx)
romkyns
@romkyns: You're right. Thanks for teaching me something new. Your link is broken, so I found information on MSDN. http://msdn.microsoft.com/en-us/library/ms686774%28VS.85%29.aspx
Adrian McCarthy
@Adrian sigh, the website has gone down less than 1 hour after I posted that link :/ Here's a google cache version of it: [The CLR commits the whole stack](http://webcache.googleusercontent.com/search?q=cache:GzcKRfKIZgoJ:www.bluebytesoftware.com/blog/PermaLink,guid,733d7537-f982-4886-af62-66bed0f97ab5.aspx)
romkyns
@Marcelo Cantos: I misspoke. A thread's stack can grow beyond the initial commit, not the initial reserve. You can commit less than the reserve in the `CreateThread` call. You can also override the default reserve for a particular thread that way. I don't agree with your "almost certainly a mistake" conclusion either.
Adrian McCarthy
+1  A: 

The memory overhead (in RAM) will be one memory page. So (depending on your platform) this will likely be 4KB.

The default stack size for both is 1MB. However that is virtual memory only, so thats no RAM overhead unless it is used.

Foxfire
This is not true for managed code. The CLR always pre-commits the thread stack of managed threads, so for CLR threads the stack is costed against the commit limit. Of course this still isn't physical memory until it is touched.
Stewart
Thats what I wrote (or wanted to). I clarified the answer to make clear that it is describing the RAM overhead.
Foxfire
+2  A: 

See the Mark Russinovich blog about win32 kernel limits for a description how big a single thread is, and how much overhead is used.

How much resources the .NET thread uses can be difficult to predict. I would guess, not much more.

Christopher
@Christopher: +1 for link
John Dibling
+1  A: 

As per the previous answers the basic overhead is 1MB per thread. I won't go into the various nuances - the other answers have them covered.

For Microsoft Visual C/C++ threads you also have the per-thread overhead of any C runtime workspace that is allocated on demand (and stored using Thread Local Storage TlsAlloc()) to perform work such as sprintf(), scanf(), strtol() etc. I don't have any exact figures - you would need to scan the source to the Microsoft CRT to calculate that.

For other C/C++ runtimes (gcc/g++/borland/digital mars) there may or may not be similar per-thread data held, its an implementation detail.

None of us know the internals of the .Net Execution Engine, but there is probably some per-thread data stored there as well. Going to be hard to figure out what that overhead is though.

Stephen Kellett