. Net FAQ sorting (2) -- packing and unpacking

Source: Internet
Author: User
In order to prevent Reprinting of the original web site, add the original link here: the previous section of the http://www.cnblogs.com/zhangkai2237/archive/2013/03/21/2974570.html we are discussing the value type and reference type, we know that the value type is a lightweight data structure. For some simple types that are defined as value types, the system overhead and GC pressure caused by defining them as reference types are reduced. However, the value type has a disadvantage: the object pointer is missing. We cannot use a new variable to reference the value type on the stack (Note: unboxed value type ). That is to say, many methods with reference types as parameters cannot input value types. To solve this problem, CLR provides a mechanism for packing and unpacking. I. Concepts and Principles of packing and unpackingDuring the interview, when the interviewer mentioned the packing and unpacking problems, many people may think of the first sentence: "packing is the process of converting the value type into the reference type; unpacking is the process of converting the reference type to the value type ". There is no problem with this sentence, but it is not a level of intermediate. Net programmers if you just say this sentence without the following. In fact, the name of packing and unpacking is very good. "box" refers to hosting the heap, and "Packing" refers to encapsulating the value type object on the stack in the hosting heap, generate a copy of the Value Type object and return the address of the copy. However, unpacking refers to returning the address of the boxed value type in the managed heap (Note: In strict sense, unpacking does not include copying of value type fields ). If you still don't understand the above section, let's take a look at what happened inside the packing and unpacking process.

# Region binning and unboxing int I = 10; object o = I; // binning Int J = (INT) O; // binning # endregion
The code above is split and packed once. The packing process is as follows:1. memory Allocation: allocate memory in the managed heap, the memory size is the sum of the memory size required by each field of the value type and the sum of the memory size required by all objects hosted on the heap have two additional members-type object pointers and synchronized block indexes. 2. Copy object: copy the field of value type to the newly allocated memory. 3. Return address: return the address of the boxed value type object to the referenced variable. Let's take a look at the packing il code: the packing operation has a very obvious sign: "box", and its execution completes the three steps we just mentioned. The unpacking process is as follows:1. check the instance: First, check whether the value of the variable is null. If yes, the nullreferenceexception is thrown. Then, check whether the object referenced by the variable is a boxed object of the specified value type. If not, an invalidcastexception is thrown. 2. Return address: return the address of the field of the original value type in the boxed instance, and the two additional members (type object pointer and synchronized block index) will not return. At this point, the unpacking process has ended, but with the unpacking, "often" (the descriptions in CLR via C # Use "often" instead of being certain, however, I do not know whether there is a kind of box-breaking without field replication so far.) A field copy operation will take place immediately. In fact, the instance field in the boxed object is copied to the memory stack. Is the Il code for unpacking: Similarly, the unpacking operation also has an obvious sign: Unbox. Note:1. Both packing and unpacking are for the value type, and the reference types are consistent in the managed heap, that is, they always exist in the form of "Packing. 2. packing and unpacking are not mutually inverse processes. In fact, the performance overhead of packing is far greater than the performance overhead of unpacking, and the field copying steps with unpacking are actually not in unpacking. 3. only the reference type after the value type is boxed can be split, and not all reference types can be split, if you forcibly convert a non-Boxed instance to a value type or a non-original value type, an invalidcastexception is thrown. 4. unbox and Unbox are included in the Il code for unpacking. the difference between any and Unbox commands is that Unbox commands do not contain field copy operations that are accompanied by box removal, but Unbox. any contains the field copy operation that is accompanied by unpacking. So far, I have not found any field copy operation in C #, So I sometimes put this operation in the unpacking step. 5. How do we know whether the reference type is the expected value Type Packing format before unpacking. We have two methods, one is to use the is/as operator to determine (for details, please move: http://www.cnblogs.com/zhangkai2237/archive/2012/12/15/2820057.html); the other is the object class GetType method. Ii. common cases of unpacking and packingFirst, let's take a look at the following code to see how many times of packing occurs:

Static void main (string [] ARGs) {# int I = 2; I. getType (); object o = I; arraylist Al = new arraylist (); Al. add (I); hashtable ht = new hashtable (); ht. add (3, I); console. writeline (I + "," + (INT) O); console. readkey (); # endregion}
If I say that the above Code has been packed for seven times, do you think it is surprising? Let's analyze this code in detail. The first line is a simple value assignment statement. The second line is to call the GetType () method. We think that the GetType method is a non-virtual method in the object type and cannot be rewritten in the subclass. Therefore, the call must use the GetType method of the object type, so a packing is performed here. In the third row, the value type variable I is assigned to the variable O that references the type object, which is also packed once. This is obvious and can be basically seen. The fourth line instantiates an arraylist object, and the fifth line adds variable I TO THE arraylist. First, let's look at the parameter types required by the arraylist. Add method:

public virtual int Add(object value);
It needs to receive the object type, so variable I needs to be packed here. Similarly, rows 6 and 7 instantiate a hashtable object and add I to it. The hashtable. Add method also requires two parameters of the object type, so the seventh row will pack 3 and I respectively.

public virtual void Add(object key, object value);
So far, the above Code has been packed five times. The console. writeline method is called in row 8. It receives a string value. However, if the int type is encountered in the tired addition, It is implicitly converted to the string type. The first part of the method parameter I needs to be boxed, and the third part is to forcibly convert the object type to the int type before packing the int type to the string type. So this step is packed twice. To sum up, we can see that these lines of code are packed up to 8 times. If you are interested, you can write and read the number of IL codes "box. In our daily work, the common implicit packing is mainly concentrated in the method. 1. The input is the reference type, but the value we pass is the value type, which will cause packing. Typical examples are arraylist and hashtable. There are also two special methods: the console. writeline method and the string. Format method. 2. The value type calls the method of the parent class. If a non-virtual method of the base class is called, it will be packed in any way; if a virtual method is called, if it is rewritten in the value type, it will not be packed. If it is not overwritten, if the method of the base class is still called, the value type will still grow. Similar to the GetType method in the previous example. Iii. How to Avoid packingThe reason why we study packing and unpacking is that packing and unpacking will cause considerable performance loss (in contrast, packing is more expensive than unpacking ), performance problems are mainly reflected in the execution speed and field replication. Therefore, we should try to avoid packing and unpacking when writing code. The commonly used methods are as follows: 1. Use the overload method. To avoid packing, many methods in FCL provide many methods for overloading. For example, the console. writeline method we discussed earlier provides up to 19 overload methods to reduce the number of value-Type Packing times. For example, see the following code:

Console.WriteLine(3);
At the beginning, you may reject the value 3 of the string type, but in fact this statement will not be boxed, because the console. writeline method has an overloaded method, and the parameter is an int value.

public static void WriteLine(int value);
Similar to console. the writeline method, and the system. io. the write method of binarywriter, system. io. the write and writeline methods of textwriter, system. text. the append and insert methods of stringbuilder provide a large number of overload methods to reduce the number of times of packing. Therefore, in actual projects, we should always pay attention to the case of packing, and choose a suitable method to overload to avoid packing. 2. Use generic. Because of the performance problems of packing and unpacking, generic type is referenced in. NET 2.0. Its main purpose is to avoid packing and unpacking between value types and reference types. Common collection classes have generic versions. For example, arraylist corresponds to a generic list <t>, and hashtable corresponds to a dictionary <tkey, tvalue>. Generic knowledge is not the focus of this article. I will have the opportunity to summarize it later. 3. If a value type variable in the project needs to be disassembled multiple times, you can propose this variable for explicit packing. For example, the following code:

int j = 3;ArrayList a = new ArrayList();for (int i = 0; i < 100; i++){    a.Add(j);}
It can be changed:

int j = 3;object ob = j;ArrayList a = new ArrayList();for (int i = 0; i < 100; i++){    a.Add(ob);}
4. tostring. This is listed separately because it is small but practical. Although the value type calls the tostring Method for packing, because tostring is a method inherited from the base class. However, the tostring method is a virtual method, and the value type is generally overwritten. Therefore, the method called tostring is not boxed. As mentioned before, the string. Format method is easy to cause packing. The best way to avoid this is to call the tostring method once for all value type parameters before calling this method. The value type and reference type in the previous article (original address: http://www.cnblogs.com/zhangkai2237/archive/2013/03/17/2964528.html), the packing and unpacking of this article are two key types, after understanding these concepts, it will be of great help to your future work. Of course there are some other types of content to be explained, including some basic knowledge (see http://www.cnblogs.com/zhangkai2237/archive/2012/12/15/2820057.html ), the contents of the primitive type, string type, object equality, and dynamic type are not included in this interview series, and will be written out later. The next article will explain the connection and differences between interfaces and classes. The differences between abstract classes and interfaces that are frequently used in the interview will also be involved. I hope this series of articles will be helpful to you. If there is anything wrong or you need to discuss it with me, you can leave a message below. I will visit the blog garden every day.

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.