The stack records active method calls. Each call adds a stack frame; when the method finishes, its frame is removed and execution returns to its caller. A frame keeps the information needed for that return, including local variables, arguments, and a return address. section 10.3 section 10.3.4
Reading a call stack
If CheckJokes calls a Newtonsoft test method, which calls DeserializeObject, the stack runs from CheckJokes at the bottom to DeserializeObject at the top. A profiler can inspect an executing thread’s frames and match them to symbols such as assembly, class, and method names. That makes a stack useful for connecting CPU activity to the code that led to it. section 10.3
The stack is distinct from the heap. A called function gets its own frame rather than manipulating its caller’s stack variables. The heap holds dynamically allocated memory; code with an appropriate reference or pointer can access it. This distinction matters when an array’s size is known only at runtime. section 10.3.4
A runtime-sized array
In C#, `int[] arr = new int[count];` creates an array whose length comes from `count`. The method can fill it and return it. Do not treat the array’s dynamically allocated storage as though it were the method’s stack frame: the frame is removed when the call completes, while the returned array remains available to its caller. section 10.3.4
Recursion makes stack growth visible: every invocation needs another frame. Too many recursive calls can exceed the stack’s maximum size and cause a stack overflow. section 10.3.4
The frame diagram makes the order of nested calls visible while DeserializeObject is executing. section 10.3













