CLR via C # Note 3,

Source: Internet
Author: User
Tags microsoft c

CLR via C # Note 3,
Primitive types of programming languagesSome data types are so commonly used that many compilers allow code to manipulate them with simplified syntax. System. int32 a = new System. int32 (); // a = 0a = 1; equivalent to: int a = 1; this syntax not only enhances the readability of the code, but also the generated IL code and the use of System. the IL code generated when Int32 is completely consistent. The data types directly supported by the compiler are called primitive types ). The primitive type is directly mapped to the type existing in the Framework class library (FCL. For example, in C #, int Is directly mapped to the System. Int32 type. The C # Language Specification says: "in terms of style, it is best to use a keyword instead of a complete system type name ." In fact, it is better to use the FCL type name to avoid using the primitive type name. CLR supports two types: reference type and value type. Most types in FCL are reference types, but the most commonly used type is value type.Reference TypeThe reference type is always allocated from the hosting stack. The new operator of C # returns the memory address of the object-that is, the memory address pointing to the object data. When using the reference type, you must note some performance issues, that is, the fact: #1. The memory must be allocated from the managed stack #2. Each object allocated on the stack has some additional members, these members must be initialized. #3. Other bytes of the object (set for fields) are always set to 0. #4. when an object is allocated from the managed stack, a garbage collection operation may be executed forcibly.Value TypeTo maximize performance and improve the performance of simple and common types, CLR provides a lightweight type named "value type. Value types are generally allocated on the thread stack (because they are also embedded into a reference type object as fields ). A variable that represents a value type instance does not contain a pointer to the instance. On the contrary, if a value type variable contains the field (value) of the instance, you do not need to obtain a pointer when operating on the field in the instance. Value-type instances are not controlled by the garbage collector. The design and use of value types have the following advantages: #1, which relieves the pressure in the managed heap #2, this reduces the number of garbage collection times required by an application during its retention period. The custom value type cannot have a base type, but one or more interfaces can be implemented. In addition, all value types are implicitly sealed to prevent a value type from being used as the base type of any other reference type or value type. When designing your own types, consider whether to define a type as a value type rather than a reference type. In some cases, value types provide better performance. The value type does not allocate memory on the heap. Therefore, once the method for defining this type of instance is not active, the storage allocated to them will be released, this also means that the type of instance will not receive a notification through the Finalize method when its memory is recycled.How does CLR control the layout of fields in a type?To improve performance, CLR can arrange fields of the type in any way it chooses. For example, CLR can reschedule the field order in the memory to divide object references into a group, and correctly arrange and fill data fields. However, when defining a type, you can indicate whether the CLR is arranged strictly in the specified order or re-arranged in the way that the CLR thinks fit. System. Runtime. InteropServices. StructLayoutAttribute. This is reflected in what the CLR-oriented compiler does. For example, Microsoft C # compiler selects LayoutKind. Auto as the reference type (class) by default, and LayoutKind. Sequential as the value type (structure.Binning and unboxing value typesValue types are lighter than reference types because they are not allocated as objects in the managed heap and will not be garbage collected or referenced by pointers. In many cases, you must obtain a reference to an instance of the Peer value type. To obtain a reference to an instance of the value type, the instance must be boxed. The Add method of the ArrayList Object is public virtual Int32 Add (Object value). ArrayList. Add needs to obtain a reference (or pointer) to an Object on the managed stack as a parameter. To populate ArrayList with a set of Int32 numbers, the Int32 number must be converted into a real, hosted heap object and a reference to this object is obtained. To convert a value type to a reference type, you must use a mechanism named boxing. What happens internally when a value-type instance is boxed: #1. Allocate the memory in the managed heap. The amount of memory allocated is the amount of memory required for each field of value type plus the amount of memory required for two additional members (type object pointers and synchronized block indexes) for all objects hosted on the heap. #2. Copy the value type field to the newly allocated pair memory. #3. Return the object address. This address is a reference to this object, and the value type is now a reference type. Note that the lifetime of the boxed Value Type exceeds that of the unboxed value type. FCL now contains a new set of generic collection classes that make non-generic collection classes obsolete. For example, the wildcard collection classes are greatly enhanced, and the performance is also significantly improved. One of the biggest enhancements is that the generic collection class allows developers to bind or unpack items in a set of value types. In addition to improving the performance, the type security during compilation is also achieved, and the source code becomes clearer because of the decrease in the number of forced type conversions. After packing, you may need to unpack the box. Unpacking is not a matter of packing, but its cost is much lower than packing. For example, Int32 I = (Int32) a [0]; The binning operation is divided into two steps: #1. Obtain the address of each field in the boxed object. This process is the binning. #2. Copy the values contained in these fields from the heap to the value type instance based on the stack (thread stack. Simply put, if you get a reference to an instance of the Peer value type, the instance must be packed. The preceding ArrayList. Add method transmits a value type instance to a reference type method. As mentioned above, the unboxed value type is more lightweight than the reference type. This is due to two reasons: #1. They are not allocated on the hosting stack. #2. They do not have any additional members for each object on the stack, that is, a "type Object Pointer" and a "synchronized block Index ". Therefore, because unboxed value types do not have synchronized block indexes, System cannot be used. threading. various methods of the Monitor type (or the lock Statement of C #) Allow multiple threads to synchronously access this instance.Description of value types:#1. The value type can override the Virtual Methods of Equals, GetHashCode, or ToString. CLR can call this method non-virtual, because the value type is implicitly sealed (that is, there is no polymorphism ), no types can be derived from them. #2. In addition, the Value Type instance used to call the method will not be boxed. However, if the virtual method you override needs to call the implementation of the method in the base class, the value type instance will be packed when the base class implementation is called, this pointer can be used to pass a reference to a heap object to the base method. #3. When the value type calls a non-virtual, inherited method (such as GetType or MemberwiseClone), the value type must be boxed in any case. This is because these methods are defined by System. Object, so these methods expect this real parameter to be a pointer to the Object on the heap. #4. to convert an unboxed instance of the value type to an interface of the type, bind the instance. This is because the interface variable must contain a reference to an object on the stack.Comments:Any. NET Framework developer must understand these concepts to ensure long-term success of their own development programs. Because only after a deep understanding can we build efficient applications faster and more easily.Important:Members defined in the value type should not modify any instance fields of the type. That is to say, the value type should be immutable. In fact, we recommend that you mark all fields of the value type as readonly. In this way, if you accidentally write a method to change a field, the compilation will fail. If a method attempts to modify the instance field of the value type, calling this method will result in unexpected behavior due to changes in the packing. After constructing a value type, if you do not call any method that will modify its status (or if such method does not exist at all ), there is no need to worry about packing and unpacking/field replication. If a value type is immutable, you only need to simply copy the same status (you don't have to worry about modifying these statuses in any way ), any behavior of the code will be under your control. Maybe you are far away from the custom value type when you see these details of the value type, or you have never used the custom value type. However, the FCL core value type (Byte, Int32 ,... and all enums are "immutable"). When you understand and remember these possible problems, you will be aware of them.Object equality and identityBy default, the Equals method of an Object implements identity instead of equality ).Object hash codeAn algorithm that allows objects of the same class to have different hash codes according to their own characteristics, but does not indicate that different object hash codes are completely different ." The hash code is the ID card of the object. "DynamicDynamic expressions are of the same type as System. Object. The compiler assumes that any operation you perform on the expression is legal, so no warning or error is generated. However, if you try to perform an invalid operation at runtime, an exception is thrown.Type and member Basics Various types of membersConstant, field, instance constructor, Type constructor, method, operator overload, conversion operator, attribute, event, TypeType visibilityPublic: not only is all the code in its definition Assembly visible, but also the code in other assembly. Internal: the type is visible only to all the code in the defined assembly and not to the Code in other assembly. If you do not explicitly specify the type visibility when defining a type, the C # compiler sets the type visibility to internal by default.Youyuan assemblyWe hope that the TeamA toolset will have a way to define its tool type as internal while still allowing team TeamB to access these types. CLR and C # provide this support through the friend assembly. If you want to include code in one assembly and perform unit tests on the internal types of the other assembly, the feature can also be used.Accessibility of membersCLR defines a set of Accessability modifiers, but each programming language selects its own set of terms and corresponding syntax when applying Accessability to members. For example, CLR uses Assembly to indicate that members are visible to all code in the same Assembly, while C # Corresponds to internal.C #:Private, protected, internal, protected internal, when a derived type is rewritten to a member defined in its base type, C # The Compiler requires that the original and rewrite members have the same accessibility. That is to say, if the base class member is protected, the override member in the derived class must also be protected. However, this is only a restriction on the C # language, rather than the CLR. When derived from a base class, CLR allows you to relax the accessibility restrictions of members, but does not allow tightening. The reason why access to a base class method in a derived class is not allowed to be stricter is that the CLR promises that the derived class can always be transformed to the base class and obtain access to the base class method. If you allow stricter access restrictions on the override method in a derived class, the promise of CLR cannot be fulfilled.Segmented classes, structures, and interfacesThis function is completely provided by the C # compiler. CLR has no idea about the division classes, structures, and interfaces. The keyword partial tells C # That the source code of a compiler, a class, structure, or interface, may be dispersed into one or more source code files.How does CLR call virtual methods, attributes, and events?Method indicates the code that executes certain operations on instances of the type or type. A static method is called an operation on a type. An operation on a type instance is called a non-static method. Each method has a name, a signature, and a return value (which can be void ).Rational use of the visibility of types and the accessibility of membersWhen using the. Net Framework, applications may be composed of the types defined by multiple assemblies that use the sound field of multiple companies. This means that developers have almost no control over the components used (assembly) and the types defined in them. Developers usually cannot access the source code (or even do not know the programming language used to create the component), and the release of different component versions is generally based on different timelines. In addition, because of polymorphism and protected (protected) members, base class developers must trust the code written by the derived class developers. Of course, developers of derived classes must also trust the Code inherited from the base class. Consider these issues carefully when designing components and types. Specifically, we should focus on how to correctly set the visibility of types and the accessibility of members to achieve the best results. When defining a new type, the compiler should generate a sealed class by default so that it cannot be used as a base class. However, many compilers, including the C # compiler, generate non-sealed classes by default. Of course, developers are allowed to explicitly mark the new type as sealed. The reason why the sealing class is better than the non-sealing class is as follows: #1. Version Control: the class starts to be sealed and will be changed to non-sealed without compromising compatibility in the future. Otherwise. #2. Performance: if the class is sealed, no derived class will be available. When calling a method, you do not need to determine which type defines the method to be called, that is, you do not need to search for the object type at runtime, but directly call the virtual method in non-virtual mode. #3. Security and predictability: A derived class can be used to override the virtual method of the base class or directly implement the virtual method in the base class. Once a method, attribute, or event is set to virtual, the base class loses some control over its behavior and status. The following are some principles that will be followed when defining a category: Extended reading: each application must use one or more resources, such as files, memory buffers, screen space, network connections, and database resources. In fact, in an object-oriented environment, each type represents a resource available for the program. To use these resources, you must allocate memory for the resource type. To access a resource, perform the following steps: #1. Call the IL command newobj to allocate memory for the resource type. C # uses the new operator to automatically generate the command. #2. initialize the memory and set the initial state of the resource to make the resource available. The instance constructor is responsible for setting the initial status. #3. Access type members (which can be used repeatedly as needed) to use resources. #4. Destroy the resource status for cleanup. #5. Release the memory. Garbage collection is solely responsible for this step. Note that you do not need to perform special cleanup operations on resources of the value type (including all enumeration types), set type, String, Attribute, Delegate, and Exception types. For example, as long as the character array maintained in the memory of the object is destroyed, a String resource will be completely cleared. CLR requires that all resources be allocated from managed heap. Objects not required by the application are automatically cleared. Then, "How does the managed heap know that the application no longer uses an object ?" During process initialization, CLR reserves a contiguous address space, which initially does not have the physical memory space of the object. This address space is the hosting heap. The managed heap also maintains a pointer, which I call NextObjPtr. Point to the allocation location of the next object in the heap. At the beginning, NextObjPtr was set as the base address of the reserved address space. The IL command newobj is used to create an object. Many languages provide a new operator, which causes the compiler to generate a newobj command in the method's IL code. The newobj command causes the CLR to execute the following steps: #1. The number of bytes required for fields of the computing type (extremely all base types. #2, plus the number of bytes required for field overhead. Each object has two overhead fields: A type object pointer and a synchronized block index. #3. CLR checks whether the reserved region can provide the number of bytes required for object allocation. If necessary, it submits the storage (commit storage ). If the managed heap has enough available space, the object will be placed. The object is placed at the address pointed to by the NextObjPtr pointer, and the allocated bytes are cleared. Next, the call type instance Constructor (passing NextObjPtr for this parameter), The IL command newobj (or the C # new operator) will return the object address. Before the address is returned, the value of the NextObjPtr pointer will be added with the number of bytes occupied by the object. In this way, a new value will be obtained, pointing to the address when the next object is placed in the managed heap. For comparison, let's take a look at how the heap allocates memory during the C language runtime. It allocates memory for objects and needs to traverse a linked list composed of data structures. Once a large enough block is found, the block will be split, and the pointer in the linked list node will be modified to ensure the integrity of the linked list. For managed heaps, assigning objects only needs to add a value to a pointer-this is obviously much faster. In fact, allocating objects from the managed stack is almost as fast as allocating memory from the thread stack! In addition, most heap (C Runtime heap) Allocate objects where they find available space. Therefore, if several objects are created consecutively, these objects are most likely to be dispersed, with MB of address space separated between them. However, in the managed heap, objects that are continuously allocated can ensure that they are continuous in the memory. Managed heap seems to be far better than normal heap in terms of implementation simplicity and speed, such as C Runtime heap. The hosting Heap has these advantages because it makes a bold assumption that address space and storage are infinite. This assumption is obviously not true, that is to say, the managed heap must allow it to make such assumptions through a mechanism. This mechanism is the garbage collector.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.