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.
Related
I read the answer to some of the similar questions but my question is little different due to fact that I do not understand a statement written about this in a book.
Because a struct is a value type, each instance does not require
instantiation of an object on the heap; this incurs a useful savings
when creating many instances of a type. For instance, creating an
array of value type requires only a single heap allocation.
I mean How can array require only a single heap allocation?... or what does it mean by single heap allocation
How can array require only a single heap allocation?... or what does it mean by single heap allocation
First of all, let's clarify what we mean by "heap" vs "stack".
Most programming environments today are stack-based. As you run a program, each time you call a method a new entry is pushed onto a special stack provided for your program. This stack entry (or frame) tells the system where to look for the method's executable code, what arguments were passed, and exactly where to return to in the calling code after the method exits. When a method finishes, it's entry is removed (popped) from the stack, so the program can go back to the previous method. When the stack is empty, the program has finished.1 There is often support for this special stack directly in the CPU.
The memory for the stack is allocated when the program is first launched, which means the stack itself has a fixed (limited) size. This is where "Stack Overflows" come from; get too deep down too many method calls, and the stack will run out of space. Each frame on the stack also has a certain amount of space for local variables for the method, and this is the memory we're talking about when we say value types live on the stack. The local variables stored on the stack do not require new allocations; the memory is already there. Just remember: this only applies in the context of local variables in a method.
The heap, on the other hand, is memory not automatically granted to the program. It is memory the program must request above and beyond it's core allocation. Heap memory has to be managed more carefully (so it doesn't leak — but we have a garbage collector to help with this), but there is (usually) much more of it available. Because it has to be granted by the operating system on request, initial allocations for the heap are also a little slower than memory used from the stack.2 For reference types, you can think of the new keyword as requesting a new heap memory allocation.
As a broad generalization, we say reference types are allocated on the heap, and value types are allocated on the stack (though there are plenty of exceptions for this3).
Now we understand this much, we can start to look at how .Net handles arrays.
The core array type itself is a reference type. What I mean is, for any given type T, the T may (or may not) be a value type, but an array of T (T[]) is always a reference type. In the "stack vs heap" context, this means creating a new array is a heap allocation, even if T is a value type. Arrays in .Net also have a fixed size4.
An additional attribute of value types is they also have a known/fixed size, based on the members. Therefore, an array of value types has a fixed number of elements, each with a known fixed size. That's enough information so allocating a new array of value types will get all the space for the array object and it's elements in single heap allocation. The value of each item (not just a reference) is held right there with the array's core memory. Now we have a bunch of value-type objects, but their memory is on the heap, rather than the stack.
This can be further complicated by a value type with one or more reference type members. In this situation, the space for the value type is allocated as normal, but the the part of the value for the reference members is just a reference. It still requires separate allocations or assignments to populate those reference members.
For an array holding reference types, the initial heap allocation for the array still allocates space for all the elements, but space reserved for each element is only enough for the reference. That is, initially each element in the array is still null. To populate the array you must still set those references to objects in memory, either by assigning existing objects or allocating new ones.
Finally, just as we were able to use arrays to get a value-type onto the heap, instead of the stack, there are also ways to force reference types to allocate from the stack. However, generally you should not do this unless you really understand the full implications.
1) There are different conventions on exactly when a frame is pushed/popped for each method call, depending on the platform, compiler configuration, and more, so only look at this paragraph for the general idea; the exact specifics will be incorrect in some particulars on any given platform.
2) For future reading, it is also useful to understand how programs handle addressing for heap memory.
3) Eric Lippert has an excellent write-up of this topic.
4) That is, arrays in .Net they are true arrays in the full formal computer science sense, unlike the associative array-like collection types in many other platforms. .Net has these, too, but it calls them what they are: collections rather than arrays.
An array is itself a reference type, which means, it is allocated on the managed heap. But if it is an array of a value type, it reserves the the memory needed for its size in one single step. Lets you have a struct with 4 Int32 in it.
A struct4Int[1000] will allocate 16000 bytes in one step.
An array of a reference type will take only the memory needed for the referencing (32bit or 64bit per item, depending on the architecture you are compiling for). Lets say a class with 4Int32 in it.
A class4Int[1000] will allocate 4000 or 8000 bytes at first.
The items are filled with the address of the references, which is intially null.
After creating the array you will have to allocate memory for every instance of the reference type and putting it's reference into the array (multiple allocations on the heap), adding another 16000 bytes on the heap in 1000 small pieces.
I was going through type values in C# and learned that they don't get allocated on the heap as normal reference types do. How does a struct with reference type get allocated?
e.g.
struct simple{
public Employee e;
public bool topEmployee;
public void printSomething()
{
Console.WriteLine("Progress " + e.GetProgressReport());
Console.WriteLine("TopEmployee " + topEmployee);
}
};
The Employee is a class. Will e get allocated to a heap when initialized? Does it defeat the point of having a struct?
The "kind" of type (value/reference) has little to do with how instances are allocated. It's all about life time, and there are more ways to allocate than "heap" and "stack". Read The Truth About Value Types.
But insofar your question makes sense: A struct's member types do not affect how struct instances are allocated, because they do not affect the lifetime of the object. Same goes for classes, by the way.
The member e will be a part of the value type object and allocated where it may be. This member is a reference, and hence any actual Employee object e refers to will be allocated somewhere else1. Though it sounds like one, this is not a special rule; locals and class members and array items behave the same way. It does not defeat the point of value types, rather maintains the benefits of both value and reference types. The value type instances are still separate values instead of being aliased, and they still have simpler and shorter life time allowing better allocation choices with less effort. The reference type instances are still shared and (potentially) long-lived.
1 At least conceptually and in the current implementations; in very simple cases optimizations (escape analysis+allocation sinking) could merge these allocations, but no CLR I'm aware of does that.
Struct memory is allocated 'in-line'. Class memory is allocated on the heap, with a reference (pointer) allocated 'in-line'.
If you see a class variable named C in a program, the storage for that variable will be equivalent to a pointer (say 4 bytes), and the actual storage for the class will be on the heap.
But if you see a struct variable named S in a program, the storage for that variable is simply the size of the variable at the point of declaration. There is no heap allocated storage for it.
If C contains an S then S will be located in the heap storage for C.
If S contains a C then the reference to C will be located in the storage for S, and the storage for C is on the heap. This is the answer to your question about simple and e.
So struct storage can actually be in static memory, on the stack or on the heap (inside a class). Class memory is always on the heap.
The reference variable 'e' will be allocated wherever the struct is allocated (e.g. a local variable of unboxed struct type is likely to go on stack). The instance of Employee the 'e' is pointing to will be allocated on heap. This may vary between .NET implementations, but is most likely true for all current implementations.
Simple code for example:
Object test=new Object();
I understand that memory for test object allocated into heap.
Quote from MSDN:
Variables of reference types store references to their data (objects)
But I really can't understand where stored this variable values (references to heap data), into stack or into heap or another place?
test variable is stored on stack - it holds address of object on heap. And object instance is stored on heap.
I suggest you to read .NET Type Fundamentals article by Jeffrey Richter:
When an object is allocated from the managed heap, the new operator
returns the memory address of the object. You usually store this
address in a variable. This is called a reference type variable
because the variable does not actually contain the object's bits;
instead, the variable refers to the object's bits.
In addition to reference types, the virtual object system supports
lightweight types called value types. Value type objects cannot be
allocated on the garbage-collected heap, and the variable representing
the object does not contain a pointer to an object; the variable
contains the object itself. Since the variable contains the object, a
pointer does not have to be dereferenced in order to manipulate the
object. This, of course, improves performance.
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.
I think the GC may treat reference type and value type differently.
GC will collect the reference type if there is nobody have a reference to it.
When GC will collect the value type like struct? My struct is not small. I want it be collected as earlier as possible. With a profiler software, I saw that struct has a big accumulation and is the major memory consummer.
A struct will only be in the managed heap (i.e. where it can be garbage collected) if it's either an instance/static field, or as part of another object, or boxed, or in an array1. It's never "naked" in the managed heap - the closest you can get is a boxed value.
If you have a large struct, that's your first problem. Why have you created such a thing? Structs should almost always be small (the rule of thumb is usually 32 bytes) as otherwise every time you use it as a method argument or assign it to another variable, you'll end up copying it.
Have you considered using a class instead?
1 As Eric Lippert is fond of pointing out, the stack is an implementation detail. Furthermore, in certain cases local variables end up as fields in autogenerated classes... but that's somewhat irrelevant for this question, I believe.
A struct type is a value-type and inherits from System.ValueType. Value-type variable is allocated on the current thread's stack (not on the heap). Memory is not allocated on the managed heap. It is allocated on the stack and is automatically freed when value-type variable go out of scope. But if you are making the boxing of value-type variable then memory is allocated on the heap for variable's wrapper and variable's fields are copied to the wrapper. If your value-type variable is larger than 85KB it's wrapper will be placed in Large Object Heap (LOH). LOH objects are long living - they belong to Gen2.