Why we limit the size of stack but not heap in memory

Viewed 632

I mainly program with C++. I have seen from many places that I should put large objects (like array of 10k elements) on heap (using new) but not on stack (using pure array type). I don't really understand. The reason might be because abuse of stack many result in stack overflow error at runtime. But why should OS set a limit for the stack size of a process (or more precisely, a thread) as virtual memory can go as large as needed (or 4G in practice). Can anyone help me, I really have no clue.

2 Answers

Tradition, and threads.

Stacks are per thread, and for efficiency must be contiguous memory space. Non contiguous stacks make every function call more expensive.

Heaps are usually shared between threads; when they aren't, they don't have to be contiguous.

In the 32 bit days, having 1000 threads isn't impossible. At 1 meg per thread, that is 1 gigabyte of address space. And 1 meg isn't that big.

In comparison, 2 gigs of heap serves all threads.

On 64 bit systems, often addressable memory is way less than 64 bits. At 40 bits, if you gave half of the address space to stacks and you had 10,000 threads, that is a mere 50 megs per stack.

48 bits is more common, but that still leaves you with mere gigabytes of address space per stack.

In comparison, the heap has tebibytes.

What more is that with a large object on the stack doesn't help much with cache coherance; no cpu cache can hold the tront and the back. Having to follow a single pointer is trivial if you are working heavily with it, and can even ensure the stack stays in cache better.

So (a) stack size cost scales with threads (b) address space can be limited (c) the benefits of mega stacks are small.

Finally, infinite recursion is a common bug. You want your stack to blow and trap (the binary loader surrounds the stack with trap pages often) before your user shell crashes from resource exhastion. A modest size stack makes that more likely.

It's totally possible to use a static array of 10k INTs. It's usually better to use "new" because when you're dealing with big chunks of data, you can't guarantee they'll always be the size of your array. Dynamic allocation of memory lets you use only what you need. It's more efficient.

If your curious about how the OS chooses stack sizes or "pages", read this: https://en.m.wikipedia.org/wiki/Page_(computer_memory)

Also, I'm not sure you're using "heap" the right way. "heap" is a tree-based data structure. The Stack refers to the layout of the executable and process data in RAM.

Related