Stack and heap in c sharp [duplicate] - c#

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Why are structs stored on the stack while classes get stored on the heap(.NET)?
Can anyone tell me that how the allocation of memory is done that which object is to be stored in stack and which to be in heap portion of the memory?

In the Microsoft implementation of the C# compiler and CLR, value types are stored on the stack when the value is a temporary value, local variable or formal parameter, that is neither a closed-over outer variable of an anonymous method nor in an iterator block.
Of course, why store stuff on the stack if you don't need to? Some local variables of value type never get on the stack at all; they stay in registers for their entire lifetimes.
Other values of value types are stored on the heap - boxed value types, value-typed fields on a reference type, and so on.
Value types can of course be stored on neither the stack, nor registers, nor the managed heap; they could be stored in unmanaged memory using some completely other memory manager not under control of the CLR.
(And of course note that using "the" in "the stack" is subtly misleading; there can be many stacks in a process. There need not be just one.)
All this is an implementation detail and subject to change without notice.
Also, obviously stuff allocated with the stack alloc declaration is allocated on the stack.
For more information on this topic see my articles on it:
http://blogs.msdn.com/b/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx
http://blogs.msdn.com/b/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx
Why do you care? The runtime manages all these details for you so that you don't have to worry about it. Are you just curious, or is this leading to some larger question?

3 rules of thumb:
Objects are stored on the heap. These include instances of reference-types and boxed value-types.
Local variables and parameters are stored on the stack. For local value-types, this means that the value itself is stored on the stack. For local reference-types, only the reference will be on the stack (Edit: Exceptions noted by Eric Lippert - value-type locals closed over outer variables, iterator-block value-types).
Fields are stored where the containing instance is located. For example, a value-type field of a class will be stored on the heap. The reference-part of a reference-type field of a struct declared as a local stored on the stack will also be on the stack.

Related

Is stack memory only for pointers and heap for objects?

Firstly, I'm currently working in C# and I've been reading up on memory management. So far, I've read through some great answers on stack overflow explaining the difference between stack memory and the managed heap memory. The majority of the answers state that by declaring:
int x = 5, you're allocating enough memory for the type of x within the stack memory.
I understand how this works as well as the scope of it, however when I read the explanation of heap memory, it confused me.
If you're saying int x = 5, since int is an alias of System.Int32, wouldn't x technically be a pointer to a new instance of the System.Int32 struct? And if so, wouldn't it then be stored in the heap memory since that's used for instance objects.
In this tutorial, it states (for the line class1 cls1 = new class1()):
... creates a pointer on the stack and the actual object is stored in a different type of memory location called ‘Heap’.By this logic, isn't everything stored on the heap and only pointers stored on the stack? Examples being new instances of System.String, System.Int64, System.Boolean, System.Decimal etc.
I thought I understood it, however clearly I don't, so I would appreciate someone explaining whether the stack is only for pointers or which part I've misinterpreted. Thanks in advance.
You can use the following rule: if it's a struct (including primitive types) then it's allocated where it's declared, otherwise a pointer to an object in heap is allocated.
Possible locations are:
For local variables it's a stack. Note that physically values can be stored in CPU registers rather than in stack.
For class fields it's inside of contiguous chunk of memory allocated in heap for an instance of the class.
For static fields it's allocated in loader heap as a part of type metadata (сorrect me if I am wrong).
Warning: this is just basic, non-comprehensive explanation to have a basic understanding of what's going on. The reality is more complicated. Local variables can be hoisted and moved to heap, optimizer can eliminate them altogether, etc...
You may want to check Classes and structs (MSDN) to understand what is stored where and how:
int x = 1; // 32 bits holding an integer in the stack
System.Object bo = x; // 32+some more bits are on the heap to hold the "boxed" (wrapped to be kept on the heap) integer value
System.Object ho = new Object(); // some bits are created on the heap right from the start
In simple words there are two types of objects: classes and structs. The classes (reference types) are meant to be stored on the heap and have a pointer to them while structs are meant to be stored in the stack (the structs can be relocated to the heap though with a little overhead of wrapping("boxing") them).
If you really need/want to understand how CLR works in general, consider reading "CLR via C#" (Richter).

Should the stack be really allocated in a C# program?

From what I know of C# (I believe I am right), value types are allocated on the stack and reference types are alllocated on the heap. But if a field in a class is value type, it is allocated on the heap rather than on the stack (I'm still right, right?).
With that said, I also know that every C# program is a class and is made up of classes. That should imply that any variable declared in a C# program, value type or reference type, should be allocated on the heap.
What I can infer, then, is that the stack may not be really used in a C# program. I say 'may' because there could be extraordinary cases, not that I know one, though.
You are mostly correct :)
Variables that are local to a method, however, are indeed allocated from the stack. This is the whole truth for value types. For reference types, the actual object, string, array, and so on, is allocated on the heap, but the pointer itself is allocated on stack.
A reference type is stored in the heap. This is true for the value types that are contained in the reference type. On the contrary in the stack is stored the reference to the object that is stored in the heap.
Regarding the variables that are local to a method that 500 - Internal Server Error has pointed out holds. They are allocated to the stack.

How are arrays created and accessed

I understand(not completely why, though) that instances of primitive types such as int, float are stored on the stack and are not heap allocated. But I am a bit confused about how arrays of primitive types are stored and accessed. I have this question because System.Array is a reference type. And reference types are heap allocated.
int[] integers = {1,2,3,4,5};
How are these individual integers stored and accessed on the memory?
Your "understanding" is flawed, basically. Value type values are sometimes stored on the stack - but not when part of an array or any other heap-based object. It's unfortunate that some people choose to make such a blanket statement around value types living on the stack, which then confuses others :(
Besides, the stack/heap distinction is an implementation detail...
See my article on memory for some more details, but definitely read Eric Lippert's blog post (linked in the previous paragraph) for more philosophical considerations. (Read his other posts on value types for even more information.)
You have discovered the reason why the statement "value types are always stored on the stack" is obviously wrong. The truth is that the type of the object being stored is irrelevant to where it is stored. The correct rule is that values with short lifetimes are stored in storage from the short-term "stack" and values with long lifetimes are stored in storage from the long-term "heap".
When you put it that way, it is practically a tautology. Obviously short-lived stuff is allocated from the short-term store, and long-lived stuff is allocated from the long-lived store! How could it be otherwise? But when you put it that way, clearly the type is irrelevant except insofar as the type gives you a hint about the lifetime.
The contents of an array of ints is potentially long-lived, so the ints are allocated from the long-term store. The contents of a local variable of type int is typically short-lived, so it is typically allocated from the short-lived store.
Array itself is always a reference type, so it's stored on heap. Elements of an array are stored on heap too, but always in a contiguous block of memory.
This article by Jeffry richter written back in 2002 explains this concept very clearly.

How will an object with a value type and reference type be stored in .NET?

In .NET, integer data type is a value type(stack) and String is a reference type(heap).
So If a class A has an integer, and a string type object in it, and a class B creates an object of class A, then how will this object of class A be stored in memory? In stack, or in a heap?
This was asked in my Microsoft interview. Need to understand how I fared.
Eric Lippert just wrote about this:
It is simply false that the choice of whether to use the stack or the heap has anything fundamentally to do with the type of the thing being stored.
The true story is:
"in the Microsoft implementation of C# on the desktop CLR, value types are stored on the stack when the value is a local variable or temporary that is not a closed-over local variable of a lambda or anonymous method, and the method body is not an iterator block, and the jitter chooses to not enregister the value."
Most importantly, he stresses that you simply should not care where a type lives. You should care where things of a certain lifetime live.
In general, only value types that are local variables end up on the stack. The rest, including fields of classes, is stored on the heap.
In fact, the situation is more complex; see the link to Eric Lippert's Blog provided in Rex M's answer.
If I recall correctly, Objects are always reference types, regardless of their member types.
So, any object of Class A will be stored on the heap.
It was just a tricky question. I think the question was asked to you to check your knowledge about classes in dotnet. Classes are reference type. So in simple words it will go to the heap section.

Why are structs stored on the stack while classes get stored on the heap(.NET)?

I know that one of the differences between classes and structs is that struct instances get stored on stack and class instances(objects) are stored on the heap.
Since classes and structs are very similar. Does anybody know the difference for this particular distinction?
(edited to cover points in comments)
To emphasise: there are differences and similarities between value-types and reference-types, but those differences have nothing to do with stack vs heap, and everything to do with copy-semantics vs reference-semantics. In particular, if we do:
Foo first = new Foo { Bar = 123 };
Foo second = first;
Then are "first" and "second" talking about the same copy of Foo? or different copies? It just so happens that the stack is a convenient and efficient way of handling value-types as variables. But that is an implementation detail.
(end edit)
Re the whole "value types go on the stack" thing... - value types don't always go on the stack;
if they are fields on a class
if they are boxed
if they are "captured variables"
if they are in an iterator block
then they go on the heap (the last two are actually just exotic examples of the first)
i.e.
class Foo {
int i; // on the heap
}
static void Foo() {
int i = 0; // on the heap due to capture
// ...
Action act = delegate {Console.WriteLine(i);};
}
static IEnumerable<int> Foo() {
int i = 0; // on the heap to do iterator block
//
yield return i;
}
Additionally, Eric Lippert (as already noted) has an excellent blog entry on this subject
It's useful in practice to be able to allocate memory on the stack for some purposes, since those allocations are very fast.
However, it's worth noting that there's no fundamental guarantee that all structs will be placed on the stack. Eric Lippert recently wrote an interesting blog entry on this topic.
Every process has a data block consists of two different allocatable memory segment. These are stack and heap. Stack is mostly serving as the program flow manager and saves local variables, parameters and returning pointers (in a case of returning from the current working function).
Classes are very complex and mostly very large types compared to value types like structs (or basic types -- ints, chars, etc.) Since stack allocation should be specialized on the efficiency of program flow, it is not serving an optimal environment to keep large objects.
Therefore, to greet both of the expectations, this seperated architecture came along.
How the compiler and run-time environment handle memory management has grown up over a long period of time. The stack memory v.s. heap memory allocation decision had a lot to do with what could be known at compile-time and what could be known at runtime. This was before managed run times.
In general, the compiler has very good control of what's on the stack, it gets to decide what is cleaned up and when based on calling conventions. The heap on the other hand, was more like the wild west. The compiler did not have good control of when things came and went. By placing function arguments on the stack, the compiler is able to make a scope -- that scope can be controlled over the lifetime of the call. This is a natural place to put value types, because they are easy to control as opposed to reference types that can hand out memory locations (pointers) to just about anyone they want.
Modern memory management changes a lot of this. The .NET runtime can take control of reference types and the managed heap through complex garbage collection and memory management algorithms. This is also a very, very deep subject.
I recommend you check out some texts on compilers -- I grew up on Aho, so I recommend that. You can also learn a lot about the subject by reading Gosling.
In some languages, like C++, objects are also value types.
To find an example for the opposite is harder, but under classic Pascal union structs could only be instantiated on the heap. (normal structs could be static)
In short: this situation is a choice, not a hard law. Since C# (and Java before it) lack procedural underpinnings, one can ask themselves why it needs structures at all.
The reason it is there, is probably a combination of needing it for external interfaces and to have a performant and tight complex (container-) type. One that is faster than class. And then it is better to make it a value type.
Marc Gravell already explained wonderfully the difference regarding how value and reference types are copied which is the main differentiation between them.
As to why value types are usually created on the stack, that's because the way they are copied allows it. The stack has some definite advantages over the heap in terms of performance, particularly because the compiler can calculate the exact position of a variable created in a certain block of code, which makes access faster.
When you create a reference type you receive a reference to the actual object which exists in the heap. There is a small level of indirection whenever you interact with the object itself. These reference types cannot be created on the stack because the lifetime of values in the stack is determined, in great part, by the structure of your code. The function frame of a method call will be popped off the stack when the function returns, for example.
With value types, however, their copy semantics allows the compiler, depending on where it was created, to place it in the stack. If you create a local variable that holds an instance of a struct in a method and then return it, a copy of it will be created, as Marc explained above. This means that the value can be safely placed in the stack, since the lifetime of the actual instance is tied to the method's function frame. Anytime you send it somewhere outside the current function a copy of it will be created, so it doesn't matter if you tie the existence of the original instance to the scope of the function. Along these lines, you can also see why value types that are captured by closures need to go in the heap: They outlive their scope because they must also be accessible from within the closure, which can be passed around freely.
If it were a reference type, then you wouldn't be returning a copy of the object, but rather a reference, which means the actual value must be stored somewhere else, otherwise, if you returned the reference and the object's lifetime was tied to the scope in which it was created, it would end up pointing to an empty space in memory.
The distinction isn't really that "Value types go on the stack, reference types on the heap". The real point is that it's usually more efficient to access objects that live in the stack, so the compiler will try and place those values it can there. It simply turns out that value types, because of their copy semantics, fit the bill better than reference types.
I believe that whether or not to use stack or heap space is the main distinction between the two, perhaps this article will shed some light on your question: Csharp classes vs structs
The main difference being that the heap may hold objects that live forever while something on the stack is temporary in that it will disappear when the enclosing callsite is exited. This is because when one enters a method it grows to hold local variables as well as the caller method. When the method exits (ab)normally eg return or because of exception each frame must be popped off the stack. Eventually the interested frame is popped and everything on it lost.
The whole point about using the stack is that it automatically implements and honours scope. A variable stored on the stack exists until the functiont that created it exits and that functions stack frame is popped. Things that have local scope are natural for stack storage things that have bigger scope are more difficult to manage on the stack. Objects on the heap can have lifetimes that are controlled in more complex ways.
Compilers always use the stack for variables - value or reference it makes little difference. A reference variable doesn't have to have its value stored on the stack - it can be anywhere and the heap makes a more efficient if the object referenced is big and if there are multiple references to it. The point is that the scope of a reference variable isn't the same as the lifetime of the object it references i.e. a variable may be destroyed by being popped off the stack but the object (on the heap) it references might live on.
If a value type is small enough you might as well store it on the stack in place of a reference to it on the heap - its lifetime is tied to the scope of the variable. If the value type is part of a larger reference type then it too could have multiple references to it and hence it is more natural to store it on the heap and dissociate its lifetime from any single reference variable.
Stack and heap are about lifetimes and the value v reference semantics is almost a by product.
Have a look at Value and Reference
Value types go on the stack, reference types go on the heap. A struct is a value type.
There is no guaruantee about this in the specification though, so it might change in future releases:)

Categories

Resources