WHAT'S NEW?
Loading...

Boxing and unboxing

Index


  • Intro
  • Types
  • Stack vs Heap
  • Nullables
  • Boxing and Unboxing
  • You are now aware of...
  • Then, why?


Intro

As a real example of what boxing and unboxing are, think about a shipments company like FedEx or DHL, they don't really know what inside of the box. If it's something flammable, volatile..., only the recipient knows how to use it. The shipper will put the package in trains, planes or whatever to reach its destination.


Types

Three different types in .Net:

  • value, 
  • reference 
  • and pointer type. 


Let's concentrate on the first two: reference types and value types. Value types (int, decimal...) have always a fixed size and the compiler knows exactly how much space needs to allocate in the stack.

With the reference type is not that easy because the compiler doesn't know how big the type is. Then, the compiler stores a fixed reference to that type in the stack. The type then will be stored in the heap. That's why arrays are reference types.

Stack vs Heap

Notice a couple of new terms have appear: stack and heap. So far, we know that value types are stored in the stack and reference types are stored in the heap. For example, every time you run into a method, the CLR places all the value types in the scope of that method within the stack. For reference types a pointer to the heap will be placed in the stack. When the method is over all those variables are deallocated from the stack.

Reference types can live longer than value types. They can live out from the scope of the method until the Garbage Collector comes and dispose them. Typically, are stored as Generation 1 variables mean while value types are Generation 2.

Stack default size is one megabyte and is configurable. The heap can store gigabytes.

Nullables

They are actually value types. They represent a type which implements the System.Nullable<T> structure. These value types have default values like 0 for int or false for bool but they can handle null value as well.

Boxing and Unboxing

Boxing wraps a value type inside of a reference type and stores it on the heap. Unboxing converts one of this wrapped object back into the stack. It basically, takes the address memory from the stack and copies the object from the heap on that reference back into the stack.

You are now aware of...

Here I want to make you aware of 7 sins you have to know when working with boxing and unboxing. This is important to avoid problems a better insight of the CLR:

  1. Boxed values take up more memory: a boxed value lives in the heap. This means we need a pointer (32b or 64b) from the stack to our reference-type in the heap as well as a sync block index (32b). This means an Int32 now takes between 92b or 128b. 3/4 times the space!
  2. Boxed values require an additional read: to fetch a boxed value you must firsts get the pointer and then look up the object.
  3. Short-lived values clog the heap: unused boxed values pile up in the heap until the GC collects them.
  4. Boxing and unboxing operations takes time/CPU: boxing requires allocate space in the heap and copy files to the stack. Unbox is cheaper as you just need the address and skip the allocation, but you usually end up copying the value data from the heap back to the stack if you want to use it. MSDN: Boxing can take 20 times longer than assign a reference. Unbox up to four times.
  5. Casting: you don't get compile time safety checks. Watch out for InvalidCastOperations.
  6. Implicit boxing: typical scenario where you are using an ArrayList which performs a boxing op. every time you Add() a new element. Another example is when you use the String.Format() and you pass values into the string by using the operators {0}, {1},... This performs a boxing operation behind the scenes which can be prevented by calling ToString()
  7. They're (almost) unnecessary: in the old days a lot of boxing/unboxing was going on specially because these big boys: ArrayList and HashTable. Those days are gone and since .Net v2 we have generic collections like List and Dictionary. 

Then, why?

Yeah! Why these two guys are still around here? This is the list of reasons why you still have to fight against the damn box:
  1. Legacy code
  2. 3rd party libraries
  3. .Net internals: using dynamic or reflection.
  4. Mixed value/references type collections: a "params" parameter is a reference type which ends up boxing the value types, ie: Console.WriteLine("{0} years old!", 30); (Anyway I'm pretty sure you'll never see performance issues from this peace of code)


References

http://www.codingblocks.net/programming/boxing-and-unboxing-7-deadly-sins/
https://msdn.microsoft.com/en-us/library/3ewxz6et.aspx
https://msdn.microsoft.com/en-us/library/ee787088(v=vs.110).aspx#generations
https://msdn.microsoft.com/en-us/library/1t3y8s4s.aspx

0 comments:

Post a Comment