1

MSDN's C# docs uses the terms stack and heap (eg. when talking about variable allocation).

It is stated that these terms means different memory spaces with well defined purposes (eg. local variables are always allocated in the stack whereas member variables of reference types are always allocated in the heap).

I understand what those terms mean in terms of certain CPU architecture and certain operating systems. Let's assume the x86-64 architecture, where the stack will be a per-thread contiguous memory block used to store call frames (local variables, return address, etc), and the heap being a one-per-process memory block for general purpose use.

What I do not understand yet is how those high-level and low-level definitions relate together.

I couldn't find an objective definition for the terms stack and heap in the MSDN docs, but I assume they mean something very similar to what those terms means in the x86-64 architecture.

For the purpose of this question, let's assume we are working on a custom device which the CPU and OS don't implement the concept of a separate stack and heap, they both (CPU/OS) deal directly with virtual memory. Will the stack and the heap (as cited in the MSDN docs) even exists in an .net application running on this particular device? If so, are they enforced by the CLR? Are they created on top of what the OS returns as allocated memory?

underthevoid
  • 513
  • 1
  • 6
  • 17
  • Does this answer your question? [Is everything in .NET an object?](https://stackoverflow.com/questions/436211/is-everything-in-net-an-object) –  Aug 14 '21 at 14:23
  • @OlivierRogier No I don't think so. I'm concerned specifically about how the `stack` and `heap` cited in MSDN C# docs are treated at the CPU/OS layer. – underthevoid Aug 14 '21 at 14:30
  • @OlivierRogier I don't agree this question should be at superuser.com rather than here. I'm literally asking about a software development question. – underthevoid Aug 14 '21 at 14:48
  • If this duplicate and all the others on Stack Overflow and their links on object, class, struct, literal, instance, immutability, boxing, memory, managed, stack, heap, static, const, local, operating system, microprocessor, CLR and so on are not responding, just go to https://superuser.com –  Aug 14 '21 at 14:50
  • @OlivierRogier which duplicate are you talking about? The link you suggested that supposedly answers this question simply does not answers this question... – underthevoid Aug 14 '21 at 14:51
  • 2
    We should not care where objects are physically located. Objects might be stored on the moon, which is made of cheese. The only thing we need to know is their *semantics*, in other words how the *logically* behave, and for that, all we need to know is that there is a *logical* stack of call frames from one method call to the next, and all local variables have by-value copy-semantics. Reference-type variables point *somewhere* and have by-reference semantics. [The stack is an implementation detail.](https://stackoverflow.com/questions/1972359/the-stack-is-an-implementation-detail-or-not) – Charlieface Aug 15 '21 at 23:17
  • @Charlieface I would happily accept that as an answer, if you want to write that down. – underthevoid Aug 18 '21 at 01:55
  • It's not really an answer, it's a reason why the question isn't valid in the first place – Charlieface Aug 18 '21 at 02:06
  • Well I felt like this addressed all my concerns, but that's okay if you don't see like that. Thanks anyway. – underthevoid Aug 18 '21 at 02:10

1 Answers1

2

Operating Systems usualy handle memory as following:

The OS allocates the memory for global and static variables when it loads the program into memory and doesn't deallocate it until the program terminates. ... The other two regions, the stack and the heap, are more dynamic - the memory is allocated and deallocated by the program as needed. (Reference needed)

The "program" - in this case the CLR - allocates/requests memory on the stack or heap from the os when needed.

How does CLR manage this?

Managed Heap

The CLR implements an Managed Heap. This in fact is an abstraction over the native heap provided by the os:

  • The Managed Heap is used to divide the Heap in further segments (Large Object Heap, ObjectHeap for example).
  • When you allocate memory on the Managed Heap you won't get back a real pointer as a return value. What you get instead is a Handle, which is a indirection to the "real" pointer. This is because the GC Collector can compact your heap and move around the objects (allocated on native heap) and thus changing the pointer address)
  • If you want to allocate memory in the unmanaged heap you need to use Marshal.AllocHGlobal or Marshal.AllocCoTaskMem
  • If code is blittable or you use the unsafe keyword you need to pin the object so it doesent get moved around by GC. Because in both cases your referring to the object via the pointer directly and not the handle...

Managed Stack

  • This is used for stackwalking

  • Ref Counting, so the GC knows when he can move an object to the next generation and so on...

So you see theres a level of abstraction over the native concepts provided by the os so it can be managed by the clr but the data at the end resides in the native stack/heap.

But what if the device/os doesn't provide a heap/stack (as stated per your question)?

CLR on a device/os without stack/heap

If the CLR would be made available on such an os without such memory segmentation, the CLR could be build seperately for that os (so it accepts the same IL and manages memory in a way it is efficient without the stack/heap). In this case the documentation would change for such systems.

-OR-

It also could be possible that the clr creates their own datastructuers within the memory and manage its own stack and heap just to virtually comform the spezifications.

Remember the CLR is always Build separately for its destination (you dont use the same CLR Sourcecode and compile it once for linux and once for windows). Heck theres even an own CLR built in Javascript (.net blazor).

But since theres no such implementation nobody really can tell (what if questions are always tricky... What if I die tomorrow, what would I do today?). There are virtually no OS around that does not split their processes in Stack/heap.

Btw you stated following:

whereas member variables are always allocated in the heap

Thats not completely true if the object itself resides on the stack (eg. struct) then the members are also allocated on the stack. A reference type always stores the pointer on the stack/heap (whereever the object resides of which it is member of) and points to an object in the heap. Local variables, eg. variables in methods, are always on the stack (value for valuetypes and pointer/handle for reference types)