Analytical .NET interview questions (02) - packing and unpacking

Reprinted from the article: http://www.pythonheidong.com/blog/article/2973/

It is one of boxing and unboxing almost all face questions in the compulsory, looks simple, it is often easier to ignore. In fact, it is not that simple, a simple question can be interpreted on many levels.

  Common interview questions:

1. What is the unpacking and packing?

2. What is the box?

3. Where the box on?

4. What is the impact of boxing and unboxing performance?

5. How to avoid stealth boxing?

6. The basic structure of the box?

7. packing process?

8. unpacking process?

9. What is the following code output? How many times were packing? How many times unpacking?

int i = 5;
object obj = i;
IFormattable ftt = i;
Console.WriteLine(System.Object.ReferenceEquals(i, obj));
Console.WriteLine(System.Object.ReferenceEquals(i, ftt));
Console.WriteLine(System.Object.ReferenceEquals(ftt, obj));
Console.WriteLine(System.Object.ReferenceEquals(i, (int)obj));
Console.WriteLine(System.Object.ReferenceEquals(i, (int)ftt));

  In layman's language boxing and unboxing

There must be fitted demolition, the demolition must have installed.

In the previous article we mentioned, all value types are inherited from System.ValueType, and System.ValueType come from it is not difficult to find System.ValueType inherited from System.Object. So Object .NET is the source of all things , almost all types from her, which is the basis for boxing and unboxing.

Of particular note is this article and the previous article are directly related, you need to understand the value of a paper type and a reference type of principle, we can better understand the content of this article.

smile basic concept

Packing and unpacking is reference types and value types of conversion, she is a bridge between value types and reference types, a basic premise is that they can be converted to each other above said: Object is the source of all things .NET

Take a look at a small example code:

            int X = 1023 ;
             Object O = X; // packing 
            int Y = ( int ) O; // unboxing

Packing : value type into a reference object is generally to an interface implemented or value type System.Object reference type;

Unpacking : reference value type to type, note, reference here is only being boxed type reference type objects;

Since different reference types and value type memory allocation from the memory execution standpoint, the packing and unpacking is bound to the presence of other copies of the data memory allocation and operation, which is the root of boxing and unboxing affect performance .

laughing out loud Packing process

int X = 1023 ;
 Object O = X; // packing

Boxed value type is to convert a reference type, the specific process:

  • 1. Application in the stack memory, the memory size of a value type size, plus additional space is fixed (reference standard types: TypeHandle index and sync blocks);
  • 2. The value of the type field value (x = 1023) copies of the newly allocated memory;
  • 3. The return address of the new reference object (reference variable for Object O)

image

As shown above, after the packing has two memory objects: a is a value type variable x, the other is the new reference object o. IL instruction corresponding packing box, packing above IL code below:

image

laughing out loud Unboxing process

int X = 1023 ;
 Object O = X; // packing 
int Y = ( int ) O; // unboxing

I understand packing, unpacking boxes reverse process is, simply, it is to convert the boxed value type reference type. Specific process:

  • 1. Check the instance object (object o) effective, whether as null, which type of boxing and unboxing of a type (int) are the same as detecting invalid, an exception is thrown;
  • 2. returns a pointer, the object is to get the packing (object o) value of the address type field value;
  • 3. Copy field, boxing objects (object o) value is copied into a type field on the stack, meaning that to create a new value type variable to store the value of the unpacking;

image

As shown above, after unpacking, to give a new value type variable y, corresponding to the IL unpacking instructions unbox, IL unboxing code is as follows:

image 

Tongue smile Boxing and unboxing and performance summary

Filled with what? What is demolished? What is the box?

Through the above-depth understanding of the principles of boxing and unboxing, it is easy to understand, value types can only boxed, demolition is a reference to the object after packing, storage box is a reference to a value type field of the object instance, stored in a box the managed heap. Only value types have packing, unpacking two states, and reference types have been in the box .

About Performance

之所以关注装箱与拆箱,主要原因就是他们的性能问题,而且在日常编码中,经常有装箱与拆箱的操作,而且这些装箱与拆箱的操作往往是在不经意时发生。一般来说,装箱的性能开销更大,这不难理解,因为引用对象的分配更加复杂,成本也更高,值类型分配在栈上,分配和释放的效率都很高。装箱过程是需要创建一个新的引用类型对象实例,拆箱过程需要创建一个值类型字段,开销更低。

为了尽量避免这种性能损失,尽量使用泛型,在代码编写中也尽量避免隐式装箱。

什么是隐式装箱?如何避免?

就是不经意的代码导致多次重复的装箱操作,看看代码就好理解了

int x = 100;
ArrayList arr = new ArrayList(3);
arr.Add(x);
arr.Add(x);
arr.Add(x);

这段代码共有多少次装箱呢?看看Add方法的定义:

image

再看看IL代码,可以准确的得到装箱的次数:

image

显示装箱可以避免隐式装箱,下面修改后的代码就只有一次装箱了。

int x = 100;
ArrayList arr = new ArrayList(3);
object o = x;
arr.Add(o);
arr.Add(o);
arr.Add(o);

  题目答案解析:

1.什么是拆箱和装箱?

装箱就是值类型转换为引用类型,拆箱就是引用类型(被装箱的对象)转换为值类型。

2.什么是箱子?

就是引用类型对象。

3.箱子放在哪里?

托管堆上。

4.装箱和拆箱有什么性能影响?

装箱和拆箱都涉及到内存的分配和对象的创建,有较大的性能影响。

5.如何避免隐身装箱?

编码中,多使用泛型、显示装箱。

6.箱子的基本结构?

上面说了,箱子就是一个引用类型对象,因此她的结构,主要包含两部分:

  • 值类型字段值;
  • 引用类型的标准配置,引用对象的额外空间:TypeHandle和同步索引块,关于这两个概念在本系列后面的文章会深入探讨。

7.装箱的过程?

  • 1.在堆中申请内存,内存大小为值类型的大小,再加上额外固定空间(引用类型的标配:TypeHandle和同步索引块);
  • 2.将值类型的字段值(x=1023)拷贝新分配的内存中;
  • 3.返回新引用对象的地址(给引用变量object o)

8.拆箱的过程?

  • 1.检查实例对象(object o)是否有效,如是否为null,其装箱的类型与拆箱的类型(int)是否一致,如检测不合法,抛出异常;
  • 2.指针返回,就是获取装箱对象(object o)中值类型字段值的地址;
  • 3.字段拷贝,把装箱对象(object o)中值类型字段值拷贝到栈上,意思就是创建一个新的值类型变量来存储拆箱后的值;

9.下面这段代码输出什么?共发生多少次装箱?多少次拆箱?

int i = 5;
object obj = i;
IFormattable ftt = i;
Console.WriteLine(System.Object.ReferenceEquals(i, obj));
Console.WriteLine(System.Object.ReferenceEquals(i, ftt));
Console.WriteLine(System.Object.ReferenceEquals(ftt, obj));
Console.WriteLine(System.Object.ReferenceEquals(i, (int)obj));
Console.WriteLine(System.Object.ReferenceEquals(i, (int)ftt));

上面代码输出如下,至于发生多少次装箱多少次拆箱,你猜?

False
False
False
False
False

 

版权所有,文章来源:http://www.cnblogs.com/anding

个人能力有限,本文内容仅供学习、探讨,欢迎指正、交流。

.NET interview questions resolve (00) - begins to talk about the series of articles & interviews index

  References:

Books: CLR via C #

Book: .NET you need to know

1.4.2 boxing and unboxing: http://book.51cto.com/art/201012/237726.htm

Reprinted from the article: http://www.pythonheidong.com/blog/article/2973/

Guess you like

Origin www.cnblogs.com/xiongbatianxiaskjdskjdksjdskdtuti/p/11356786.html