Describes the relationship between the value type and the reference type in C,
Blogs and articles about value types and reference types can be said to be full of resources. Today, I accidentally re-read this knowledge and feel that I still have a lot of new insights. Let's share this time:
CLR supports two types: Value Type and reference type. It seems that most of FCL types are reference types, but most of them are value types. The reference type is always allocated from the hosting heap. when an object is added to an instance using the new operator, the returned object memory address is stored in a variable. When using the reference type, you must understand the following four psychological factors:
1. The memory must be allocated from the managed heap.
2. Each object allocated on the stack has some additional members which must be initialized before use.
3. Other bytes in the object are always set to zero.
4. When allocating objects from managed stacks, a garbage collection may be executed forcibly.
It can be seen that the abuse of the reference type will inevitably lead to overload. Let's look at the value type again. It is a lightweight type. It is generally allocated to a thread stack and can be embedded into a reference type object. The variables that hold it do not contain pointers to instances, of course, it is not controlled by the garbage collector. Therefore, the use of value types relieves the pressure on managed heaps and reduces the number of garbage collections during the lifetime of applications.
In C #, all the classes that are called 'class' are reference types, and all value types become structures or enumerations. All structures are directly derived from the abstract type System. ValueType. In itself, Enum is derived directly from the Object, all enumeration types are derived from the System. Enum abstract type, and Enum is derived from ValueType.
When should I define my own type as a value type?
1. type behavior with primitive types (Data Types directly supported by the compiler (such as Int32 and Int64 ))
2. types do not need to be inherited from any other types.
3. No other types are generated.
4. When the value type is used as a real parameter or return value, the corresponding field needs to be copied. If the instance is too large, it will cause a certain performance loss.
Therefore, it is required that the type instance be small (within 16 bytes) and the instance be large, but it can be either passed as a method real parameter or returned from a method.
Bytes --------------------------------------------------------------------------------------------------------------------------
The differences between the value type and the reference type are roughly listed as follows:
1. The reference type is in the boxed form, and the value type is in the unboxed form. The two can also be converted to each other in a certain way (details will be discussed in the next blog)
2. The value type should not introduce any new virtual methods. All methods cannot be abstract and are implicitly sealed to prevent rewriting.
3. assign a value type variable to another value type variable and perform field-by-field replication. Pay the variable of the reference type to another reference type, and only copy the memory address. Two or more reference type variables can reference the same object on the stack. Operations on one variable may affect the objects referenced by another variable. On the contrary, value type variables are independent and do not affect each other.
4. unboxed value types are not allocated on the stack. Therefore, once an instance of this type is not active, the storage allocated to them will be released without waiting for garbage collection.
This is basically the content. Sometimes you really need to taste it slowly...