C # -- Packing Mechanism

Source: Internet
Author: User

Boxing mechanism is a topic worth discussing separately, because ignoring it makes a huge mistake without knowing it.

Let's talk about the packing process first: We will first allocate memory in the heap. The memory size is the size of all fields of the value type, the pointer of the added type object, and the bytes required to synchronize the block index, copy the value type field to the allocated memory, and return the address value of the object, that is, the reference of the object.

Binning is not a reverse operation of packing: The binning only obtains a reference, which points to a value type field. It does not require copying a field. copying a field actually takes effect after the binning, but this action will definitely happen.

You must be careful when copying fields from the packing design. However, C # has an implicit packing mechanism, which makes it difficult for us to defend against attacks in many cases. Therefore, the best practice is to explicitly convert, rather than hand over to the compiler.

If you do not believe it, refer to the following example:

 
For(IntI =0; I <1000...000; I ++){IntNumber =5; Object OBJ=Number ;}

If we need to pack every loop, and worse, this value type is a counter, then ourProgramIt will be stuck here!
Perhaps this problem is very simple. Many people will not create an object in a loop, but the implicit packing mechanism will put us into the nightmare of packing inadvertently:

 
IntNumber =5; Object OBJ=Number; number=10; Console. writeline (number+","+ (Int) OBJ );

SuchCodeHow many times are packing performed in total? The answer is three times. Console. writeline () Outputs a string, which uses the static Concat () method of string. The parameter of this method is object, number and OBJ forced to convert to int must be packed.
Okay, let's modify it:

IntNumber =5; Object=Number; number = 10;
Console. writeline (number+","+ OBJ );

Now it is twice. But I only want to do it once. What should I do? It is also very simple:

 
IntNumber =5; Object OBJ=Number; number=10; Console. writeline (number. tostring ()+","+ OBJ );

The tostring () of the call number will return a string, but the number itself will not be boxed.
It's just a small modification, but the speed of this code has improved a lot (well, this short code cannot be seen at all ).

Frequent packing not only affects the running speed of the program, but also puts a lot of pressure on memory consumption. This issue is so highly valued by CLR that many methods are overloaded to eliminate the impact of packing. For example, console. writeline () has an overloaded version corresponding to each value type.

The preceding examples do not show the hidden danger of implicit packing, because the most terrible thing is that we are unaware of this:

 
IntNumber =5; Console. writeline ("{0}, {1}, {2}", Number );

We can easily write such code, but three times of packing happened here!
To some extent, the following effects can be eliminated if the packing is displayed:

IntNumber =5; Object OBJ=Number; console. writeline ("{0}, {1}, {2}", OBJ );

This is only one time.
There is another question about packing: will the change of the original value type affect the boxed value type? The answer is no, because they are stored differently.

But if we want to modify the value type, the corresponding value type in the packing should also be modified? A good problem is complicated to implement, or even awkward:

 Public   Interface  Ichangeable {  Void Setnumber ( Int  Number );} Struct  Pratice: ichangeable {  Private   Int  _ Number;  Public Pratice ( Int  Number) {_ number = Number ;}  Public   Void Setnumber ( Int  Number ){  This . _ Number =Number ;}  Public   Override  String tostring (){  Return   "" + _ Number ;}}  Class  Program {  Public   Static   Void  Main (string [] ARGs) {pratice Pratice = New Pratice (5  ); Object OBJ = Pratice; ichangeable changeablepratice = (ichangeable) pratice;
Changeablepratice. setnumber ( 6 ); Console. writeline ( " The value for the first time is: " + Patice + " , " + OBJ); ichangeable changeableobject = (ichangeable) OBJ;
Changeableobject. setnumber ( 6 ); Console. writeline ( " The second value is: " + Pratice + " , " + OBJ );}}

We usually need to change the fields in the Value Type of the structure, so we need to make this structure implement an interface (the value type can indeed implement the interface type, I have never said that all value types are acceptable, such as int, which is incredible. At least I have never seen or want to see such a thing ). Then we saw that we wanted to forcibly convert pratice to ichangeable for the first time, but we found that the value was not changed at all! The reason is very simple. We did modify the value on the boxed pratice, but after the setnumber () method returns, this boxed object will be recycled! So it is still a pratice that has not been boxed before. The reason behind this is that obj is already a reference type and conversion to ichangeable does not require packing, while ichangeable allows us to modify a pratice field.
It is very difficult to understand this process, because it is awkward! However, this is the only method in C # That may modify the boxed value type. But don't be discouraged. As long as you change struct to class, all the previous problems are gone!

Modifying a field of the value type, especially a boxed value type, is very insecure. Therefore, we can see that the modification method is very awkward, in addition, only the structure type can be modified. For example, other value types are immutable by default, which will not cause us so much trouble.

The content of the packing mechanism is here. If I study it, I may not have time to do things. I will try again when I have new materials or ideas.

 

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.