0

After reading this and this post I ran a very simple C# program shown below:

static void Main(string[] args)
{
    Thread t = new Thread(new ThreadStart(myFunc), 2097152);
    t.start();
}

The second parameter to constructor of Thread class is size (in bytes) of stack to be allocated for the thread. The number 2097152 is equivalent of 2 Mega Bytes. But my program still works without any error? Should my program not throw an error while allocating stack space (limit being 1 MB for full application itself) for this thread or I'm missing something very obvious. Initially I was thinking that this might be a compiler check itself.

How CLR ensures the stack allocation size for a thread so that it doesn't break the bounds?

P.S. : My application is 32-bit console application

RBT
  • 24,161
  • 21
  • 159
  • 240
  • What "1 MB stack size limit" are you talking about? The default stack size for a thread is 1MB, but that's not a hard limit. And the parameter you're passing is in fact the way to modify this default. Please be more specific about what you're asking. – Peter Duniho Feb 06 '17 at 03:27
  • Where did you get the idea that a stack can only be 1MB? Since you are creating a 2MB stack, plainly your belief that a stack can only be 1MB is false, so why do you believe it? – Eric Lippert Feb 06 '17 at 03:31
  • 1
    It was my first introduction to this limit in Windows today. In fact,now I realized that this is not a limit but a configuration which is modifiable on a per-thread basis.The 1st line on [this](http://stackoverflow.com/questions/823724/stack-capacity-in-c-sharp) forum got me into a different direction - `The default stack size for a .NET application is 1 MB (default is 256 KB for 32-bit ASP.NET apps and 512 KB for 64-bit ASP.NET apps)`. Either posts I referred haven't used `per-thread` term even once in entirety. For a first timer it might not be that straight forward to comprehend. – RBT Feb 06 '17 at 05:34
  • Thanks; it is helpful for me to understand why people believe false things about programming languages. So, did you believe that every thread in a program each carved out its own space from a 1MB stack buffer? So if there were 1000 threads, they'd each get 1K? – Eric Lippert Feb 06 '17 at 15:35
  • Yep. I'm crystal clear now. It all started when I had declared `char textEditor[1000000000];` in `Main` method of a C Program in the morning which broke with `StackOverflow` exception. Then I realized that in C language, arrays go to stack memory area unless explicitly allocated on heap. Then I started exploring the limit of stack memory area in general. In task manager even Visual Studio was running 61 threads (max) and each thread hardly needing a handful of KBs of stack memory area I thought 1 MB limit for the entire process would be ok. Sorry I'm out of space here. – RBT Feb 07 '17 at 02:19
  • C# is my favorite language so I started exploring on it when I saw these the two posts I've referred in my question. So I created a notion that it is a per-process limit which turned out to be false in the end. In the end it turned out to be the fact that configuration-wise it applicable on a per-process basis which gets applied to individual threads. So for 1000 threads, 1000 MB of stack buffer would get allocated if they all started running in parallel. – RBT Feb 07 '17 at 02:19
  • 1
    Thanks, that's helpful. And yes, now you see why threads are *insanely expensive*. A thousand threads will each reserve a million bytes of address space. That's why you never make a thousand threads. You make one thread per CPU and pool them. A thread comes out of the pool while you're using it, goes back in the pool when you're done, and you don't make more threads than you have CPUs to process them. – Eric Lippert Feb 07 '17 at 20:00

2 Answers2

4

1MB is just the default stack size per thread, not for the whole application. Each thread has its own stack. When you specify a different stack size in the thread constructor you are overriding the default for that thread.

If you want to test the limits of the stack size you would need to call a recursive function until the stack is filled up and overflows (hence this website's name). Simply creating more threads will just create more stacks.

Mike Marynowski
  • 3,156
  • 22
  • 32
  • 1
    Now I got it. It is not a limit at all but a configurable value associated with a thread instead which can be modified. 1 MB is the default configuration assumed by windows if we don't specify anything during creation of a thread. Once we set this value then it becomes a limit which throws `StackOverflow` exception if it is crossed due to storage of local method variables (which get stored on stack) or stack frames used to maintain method calls. I got a better picture now that a stack memory is very much coupled to a thread instead of a process. – RBT Feb 06 '17 at 05:41
3

As per Microsoft documentation,

"Beginning with the .NET Framework 4, only fully trusted code can set maxStackSize to a value that is greater than the default stack size (1 megabyte). If a larger value is specified for maxStackSize when code is running with partial trust, maxStackSize is ignored and the default stack size is used. No exception is thrown. Code at any trust level can set maxStackSize to a value that is less than the default stack size."

Brian
  • 25,523
  • 18
  • 82
  • 173
Amit Kumar
  • 69
  • 3
  • 1
    Very good information. Nice to know these internal details about partil-trust code limitation w.r.t. maxStackSize. – RBT Feb 08 '17 at 00:27