4

I am new to the concept of memory division in programming. I have found that size of stack is in most cases in .NET applications 1MB round. My question is: "How doesn't the stack overflow appear when in some functions I use local variables for "Image" type that is bigger than 1MB. Thanks in advance.

5 Answers 5

7

Because a StackOverflow exception has nothing to do with stack or heap memory management. Per the MSDN Documentation:

The exception that is thrown when the execution stack overflows because it contains too many nested method calls. This class cannot be inherited.

Now, if you're talking about the stack as far as the memory is concerned, then we're in a different world. The images you're storing in memory are likely held on the Large Object Heap. Memory management, and the conversation of it, is much too broad for this forum - but if you have a specific question about memory management then we can address that.

It's important that you understand that you are mixing two nomenclatures, and concepts, in your question and that there is an explicit difference between the two. I don't want you to go on thinking that you should be getting a StackOverflow exception because of large objects. I also don't want you to go on thinking that you are getting a StackOverflow exception because of large objects and memory management.

Sign up to request clarification or add additional context in comments.

5 Comments

-1 No, it doesn't have nothing to do with stack memory management, but everything. There isn't separate stacks for local variables and method calls.
@Guffa, explicitly, a StackOverflow exception has nothing to do with objects in memory. You can see that clearly from the MSDN documentation. However, if the OP is speaking of memory management then that's a different world. Please see my update.
@MichaelPerrenoud It has everything to do with memory management. A StackOverflowException occurs when the stack runs out of memory. You could, in theory, have just one or two method calls that contain 1MB worth of stack space, but in practice that's virtually impossible; the only way to do it is through lots of nested method calling. What the OP is missing is that the large object he's allocating isn't going on the stack, the stack just has a pointer to an object on the heap (or large object heap in this case).
@Servy, so you're saying that I could recursively call the same method more times if the method didn't use any stack allocation (e.g. no local variables) than if it did?
@MichaelPerrenoud Yes, that's most certainly the case. You could make a struct that held a few thousand longs, and then make a method holding a few thousand of those structs (not in an array, but in separate named variables) and burn through the stack much more quickly. There is also an unmanaged call to grab stack memory, and through that you could take up all of the stack's space in just one (unnested) method call.
6

The image itself is not stored on the stack, it is stored on the heap. Only a pointer/reference to the image is kept on the stack, which is a lot smaller.

public static void DoSomethingToImage()
{
    Image img = new Image(...);
}

In the above code fragment, the Image is allocated on the heap and a reference to the image is stored in the img variable on the stack.

Comments

4

Only local variables that are value types are allocated only on the stack. For a reference type like Image only the reference is allocated on the stack, the object is allocated on the heap.

Comments

2

Your local variables are actually references ("pointers"). Those images are not stored on the stack ;)

Comments

1

The main reason for a stack overflow error to happen is to have a large count of functions calls, an example that would through this error would be like this:

static int x = 0;

static void Main()
{
    fn();
}

static void fn()
{
    Console.WriteLine(x++);
    fn();
}

This happens due to something wrong at the code, because this usually happens after few thousands of calls.

The application above exited like this:

...
15706
15707
15708
Process is terminated due to StackOverflowException.

You could learn to see the "Call Stack" windows in the debugger, it will display the list of function calls.

5 Comments

That's not strictly true. It's possible, but highly unusual and impractical to have a method that consumes a very large amount of stack space and could cause an SOE without many nested calls. While the exception, in practice, is virtually always for that reason, it's not the only possible reason.
@Servy , I am not sure if that is true for managed dotnet/c#, according to the documentation here: msdn.microsoft.com/en-us/library/… , it notes only nested function calls, trying to declare an array like int[] i = new int[999888777]; in c# results in out of memory exception. .. I have edited my post just incase I am wrong.
Note that the documentation says "typically", not "only". That's significant. Declaring an array such as you have there would result in a single pointer going on the stack and the rest going in the heap (or in this case, large object heap). It's certainly possible to have a method consume a lot of stack space, that's just not how you do it.
@Servy , I just did a little test out of curiosity: static void fn2() { long x0 = 0 , x1 = 0 , .... , x100100 = 0 , x100101 = 0 ; } produces error: app1.cs(18,840840): error CS0204: Only 65534 locals are allowed , this: static void fn2() { long x0 = 0 , x1 = 0 , .... , x65528 = 0 , x65529 = 0 ; } and this: static void fn2() { long x0 = 0 , x1 = 0 , .... , x65528 = 0 , x65529 = 0 ; Console.WriteLine(x++); fn2(); } Never overflows. ... I think that there are inner checks that C# do to not go into a stackoverflow.
The limit on 65534 locals is actually for entirely separate reasons. If you wanted to overflow you'd probably need to make a custom struct that defines something like 65528 longs as different variables, then have a method with 65528 of those. (You shouldn't actually need quite that many before you get an SOE.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.