Working principles about stack, heap, garbage collector, value type and reference type
/*
Author: Jiangong SUN
*/
I've been long time confused about the reference type, value type, stack, heap and gabarge collector. How do they work? Today I try to clarify all these concepts by defining them, and listing their differences.
Reference type:
Answer:
String
All arrays, even if their elements are value types
Class types, such as Form
Delegates
Value type:
Answer:
value type consist of 2 main categories: struct and enum
struct include: numeric types(integral type, floating-point types, decimal), bool, user defined structs.
integral type include: sbyte, byte, char, short, ushort, int, uint, long, ulong
floating-point types include: float and double.
enumerations, since their underlying type is always SByte, Short, Integer, Long, Byte, UShort, UInteger, or ULong
float: precision:7 digits
double: precision: 15-16 digits
decimal: precision: 28-29 significant digits
Reference type vs. Value type:
Answer:
When value-type instance is created, a single space in memory is allocated to store the value.
When reference-type instance is created, only the reference to the object is created.
Elements not belong to types:
Namespaces
Modules
Events
Properties and procedures
Variables, constants, and fields
Reference vs. Pointer:
Answer:
A pointer in C language is like reference in CSharp, but pointer is more powerful than reference. For example, you can perform arithmetic on pointer.
All you can do in reference, you can do it with pointer. But not vice versa.
C# references could be implemented by opaque handles that are meaningful only to the garbage collector.
reference:
Value types store on Stack ?
Answer:
Value types sometimes store on Stack. But value types doesn't always store on Stack.
Here are the cases when value types don't store on Stack:
- Value types that are fields in a class
- Boxed value types
- Local value types that are outer variables of anonymous methods
- Local value types that are outer variables of iterator blocks
Why Value types stores on stack but reference types do not ?
Answer:
The short answer is “because they can”. And since the stack is cheap, we do put them on the stack when possible.
Stack:
Answer:
Stack is that the memory on the bottom of the stack always lives longer than the memory on the top of the stack; the stack is strictly ordered.
The objects that are going to die first are on the top, the objects that are going to die last are on the bottom. And with that guarantee, we know that the stack will never have holes, and therefore will not need compacting. We know that the stack memory will always be “freed” from the top, and therefore do not need a free list. We know that anything low-down on the stack is guaranteed alive, and so we do not need to mark or sweep.
The stack is the memory set aside as scratch space for a thread of execution. When a function is called, a block is reserved on the top of the stack for local variables and some bookkeeping data. When that function returns, the block becomes unused and can be used the next time a function is called. The stack is always reserved in a LIFO order; the most recently reserved block is always the next block to be freed. This makes it really 易做图 to keep track of the stack; freeing a block from the stack is nothing more than adjusting one pointer.
Heap:
Answer:
The heap is memory set aside for dynamic allocation. Unlike the stack, there's no enforced pattern to the allocation and deallocation of blocks from the heap; you can allocate a block at any time and free it at any time. This makes it much more complex to keep track of which parts of the heap are allocated or free at any given time; there are many custom heap allocators available to tune heap performance for different usage patterns.
reference:
Stack vs Heap:
Answer:
the choice of allocation mechanism has to do only with the known required lifetime of the storage.
There are not just only stack and heap in memory, Registers are neither on the stack or the heap, and it is perfectly legal for a value type to go in a register if there is one of the right size.
A lot of people seem to think that heap allocation is expensive and stack allocation is cheap. They are actually about the same, typically. It’s the deallocation costs – the marking and sweeping and compacting and moving memory from generation to generation – that are massive for heap memory compared to stack memory.
Better to use Stack or Heap?
Answer:
it is better to use a stack than a GC heap if you can.
Storage locations in Memory:
There are three kinds of storage locations: stack locations, heap locations, and registers.
Long-lived storage locations are always heap locations.
Short-lived storage locations are always stack locations or registers.
There are some situations in which it is difficult for the compiler or runtime to determine whether a particular storage location is short-lived or long-lived. In those cases, the prudent decision is to treat them as long-lived. In particular, the storage locations of instances of reference types are always treated as though they are long-lived, even if they are provably short-lived. Therefore they always go on the heap.
Garbage Collector:
When a garbage collection is performed there are three phases: mark, sweep and compact.
In the “mark” phase, we assume that everything in the heap is “dead”. The CLR knows what objects were “guaranteed alive” when the collection started, so those guys are marked as alive. Everything they refer to is marked as alive, and so on, until the transitive closure of live objects are all marked.
In the “sweep” phase, all the dead objects are turned into holes.
In the “compact” phase, the block is reorganized so that it is one contiguous block of live memory, free of holes.
Garbage collecton generations:
Answer:
Version 1 : in detail
the CLR collector is generational.
Objects start off in the “short lived” heap. If they survive they eventually move to the “medium lived” heap, and if they survive there long enough, they move to the “long lived” heap. The GC runs very often on the short lived heap and very seldom on the long lived heap; the idea is that we do not want to have the expense of constantly re-checking a long-lived object to see if it is still alive. But we also want short-lived objects to be reclaimed swiftly.
Version 2: working principle
When an object is first created, it is put into generation 0. When the generation 0 is filled up, the garbage collector is invoked. The objects that survive the garbage collection in the first generation are promoted onto the next higher generation, generation 1. The objects that survive garbage collection in generation 1 are promoted onto the next and the highest generation, generation 2. This algorithm works efficiently for garbage collection of objects, as it is fast. Note that generation 2 is the highest generatio
补充:软件开发 , C# ,