Tips and Tricks in a world of Mix

Heap vs. Stack

The Stack is responsible of what’s been “called”  ,is self-maintaining, meaning that it basically takes care of its own memory management. First in last out – “FILO” .Stack as a series of boxes stacked one on top of the next.When we’re done with the top box (the method is done executing) we throw it away and proceed to use the stuff in the previous box on the top of the Stack.The Stack is like the Stack of shoe boxes in the closet where we have to take off the top one to get to the one underneath it.

Heap is responsible for keeping track of our objects, its purpose is to hold information so anything in our Heap can be accessed at  any time.there are no constraints as to what can be accessed like in the Stack. we can grab what we need quickly.The Heap,handled by Garbage collection (GC), which deals with how to keep the Heap clean.

We have four main types of things we’ll be putting in the Stack and Heap as our code is executing: Value Types, Reference Types, Pointers, and Instructions.

Value Types: from System.ValueType

bool , byte,char,decimal,double,enum,float, struct..

Reference Types: and inherit from System.Object

class ,interface,delegate,object,string

Pointers: Reference to a Type

We don’t explicitly use Pointers, they are managed by the Common Language Runtime (CLR). A Pointer (or Reference) is different than a Reference Type in that when we say something is a Reference Type, it means we access it through a Pointer.A Pointer is a chunk of space in memory that points to another space in memory.A Pointer takes up space just like any other thing that we’re putting in the Stack and Heap and its value is either a memory address or null.

 

A Reference Type always goes on the Heap

Value Types and Pointers always go where they were declared.

If the value type is a poco and doesn’t implement some object , than it will enter the Stack.

public int AddFive(int pValue)
          {
               int result;
                result = pValue + 5;
               return result;
          }

heapvsstack5.gif

But if we are dealing with Pointers  even though the members are primitive types it will be entered into stack and point to the object in the heap.

public class MyInt
{
         public int MyValue;
}

public int ReturnValue2()
{
                MyInt x;
                x.MyValue = 3;
                MyInt y;
                y = x;
                y.MyValue = 4;
               return x.MyValue;
  }

heapvsstack13.gif

 

 

Each local variable is also located in Stack as being sent to the methods.

The methods have a GOTO reference (instructions) which direct them where to return after the method completed.

But if we have a big data primitive member, variable , such as some big struct it can overload the Stack.

The resolution is to use ref

Sending Value Type by ref

public void Go()

{

         MyStruct x = new MyStruct();

         DoSomething(ref x);

}

public struct MyStruct

{

            long a, b, c, d, e, f, g, h, i, j, k, l, m;

}

public void DoSomething(ref MyStruct pValue)

{

          // DO SOMETHING HERE….

}

 

 

that way the reference is only entered once in the Stack and if we’d preform that method 1000 times it’ll only add some more pointers to the reference location in the stack.

If our object is big it makes a big difference.

Important – when you are changing the local variable inside the Method where you send value by reference you are actually changing the parameter outside that method also.

 

Sending Reference Type as parameter

both x and pValue – are set into Stack as a Pointer to Object created in the Heap.

public void Go()

{

        MyInt x = new MyInt();

       x.MyValue = 2;

       DoSomething(x);

       Console.WriteLine(x.MyValue.ToString());

}

public void DoSomething(MyInt pValue)

{

            pValue.MyValue = 12345;

}

 

So to conclusion , the reference(the definition of the object) to the object going to the Stack while the Object itself enters the Heap.

If the initialization of the reference is reinitialized to some other Object than accordingly the reference(hence the Pointer) will point to the new Object that will also be created in the Heap.

 

For the objects inside the objects to be unique we would want to implement the IClonable interface initializing the inner object each time we need it . Otherwise we can end up pointing out the same object from different parent objects.

We would implement public object Clone() and will get the object returned as MyObjType .

GC –

JIT and CLR  are using the heap – list of used recourses and all that connected to them is mapped to a graph. GC gets the list of "root" object references to keep from just-in-time (JIT) compiler and common language runtime (CLR) and then recursively searches object references to build a graph of what should be kept

Roots consist of:

  • Global/Static pointers. One way to make sure our objects are not garbage collected by keeping a reference to them in a static variable.
  • Pointers on the stack. We don’t want to throw away what our application’s threads still need in order to execute.
  • CPU register pointers. Anything in the managed heap that is pointed to by a memory address in the CPU should be preserved
    Each unneeded object (one that didn’t entered the graph will be erased and the objects will reform a new memory allocation. Each deletion is taking time so it’s better to minimize the amount of created objects.

    There are situations where the GC needs to execute code to clean up non-managed resources such as files, database connections, network connections, etc. One possible way to handle this is through a finalizer.

    class Sample

    {

               ~Sample()

                {

                             // FINALIZER: CLEAN UP HERE

                 }

    }

    What it does – inserts the object to a finalization queue , when GC sees that the object is no longer needed it inserts it into a freachable queue , and only after the finalizer is executed GC will approach to remove it. (at the next generation only) – so actually it’s prolonging the life of the object and maximize the usage of the heap memory , so it’s better to implement the finalizer when and only we really need it.

    A better practice is to be sure to clean up non-managed resources. As you can imagine, it is preferable to explicitly close connections and use the IDisposable interface for cleaning up instead of a finalizer where possible.

     

    public class ResourceUser : IDisposable

    {

                #region IDisposable Members

               public void Dispose()

               {

                             // CLEAN UP HERE!!!

               }

                 #endregion

    }

     

    If you implemented Dispose and used the using , at the end the Dispose will be executed and GC will know to clean up the unneeded resource.

    public static void DoSomething()

    {

             using (ResourceUser rec = new ResourceUser())

             {

                        // DO SOMETHING

               } // DISPOSE CALLED HERE

    }

    // DON’T ACCESS rec HERE

      Statics and heap overflowed

      1)If we use  a static member inside a static method , we better lock the initialization to prevent access to the same resource by different threads.

      class Counter

      {

      private static int s_Number = 0;

      public static int GetNextNumber()

      {

      lock (typeof(Counter))

      {

      int newNumber = s_Number;

      // DO SOME STUFF

      newNumber += 1;

      s_Number = newNumber;

      return newNumber;

      }

      }

      }

      The best approach with statics will be a singleton pattern

      public class Earth {

                  private static Earth _instance = new Earth();

                  private Earth() { }

                  public static Earth GetInstance() { return _instance; }

      }

       

      Summary of

      http://www.c-sharpcorner.com/UploadFile/rmcochran/csharp_memory01122006130034PM/csharp_memory.aspx

      Leave a Reply

      Fill in your details below or click an icon to log in:

      WordPress.com Logo

      You are commenting using your WordPress.com account. Log Out / Change )

      Twitter picture

      You are commenting using your Twitter account. Log Out / Change )

      Facebook photo

      You are commenting using your Facebook account. Log Out / Change )

      Google+ photo

      You are commenting using your Google+ account. Log Out / Change )

      Connecting to %s

      Tag Cloud

      %d bloggers like this: