loading...

.NET Framework Memory Allocation

shoupn profile image Nick Shoup Updated on ・3 min read

This post was originally published on my blog Fundamentals of Code

Difference Between Types

I was recently asked a question about the difference between a reference type and a value type using C#.  This is a great question and knowing the difference or worse not knowing the difference can have serious implications on application performance and memory allocation.

In C#  classes, objects, arrays, indexers, interfaces, and strings are all reference types.  Whereas, predefined data types (int, long, float, double etc), structures, and enums are all value types.  Value types are allocated in memory directly, whereas reference types are stored in memory with pointers or references to the object, but not to the object itself.  The way in which this is handled has differing implications during run-time.

On The Stack or On the Heap Memory Allocation

As I stated above memory allocation and how data types are referenced are what separate the two data types. Value types are stored in a portion of memory called the stack and the reference types are stored in a portion of memory called the heap. Value types are stored in the stack and are a direct storage in the RAM of the value. Upon run-time, the program will allocate a portion of memory for that specific variable. A reference type, on the other hand, is merely a pointer to that object (allocation occurs on the heap). I always find it best to use an example. Below is a basic class called Point. Two properties PointX and PointY. I am going to show you how this can cause potential problems if one is unaware of the way storage of the object behaves.

class Point
    {
        public int PointX { get; set; }
        public int PointY { get; set; }

        public Point( int PointX, int PointY)
        {
            this.PointX = PointX;
            this.PointY = PointY;
        }
    }

So next in my main app, I am going to instantiate two Point objects. The first is used by creating a new object using the constructor. The second is merely assigned the original Point object that we created. Some would expect that with the reassignment of the first Point objects PointX property the second Point object would as it was when initialized. This is not the case, however, as both references are pointing to the same in-memory object (located of course on the heap).

class Program
    {
        static void Main(string[] args)
        {
            //The below variables are instantiation of a Point object.
            var point = new Point(1, 3);
            var point2 = point;

            point.PointX = 5;

            Console.WriteLine("Point X = {0}",point.PointX); //point.PointX = 5
            Console.WriteLine("Point2 X = {0}", point2.PointX); //point2.PointX = 5
            //Both are the same value resulting from referencing the same object on the heap.
            Console.Read();
        }
    }

Now a somewhat more intuitive use of variables can be seen when using value types. For example, if I create a decimal variable and assign another decimal variable to the same value, I get what I expect when returning those. Also if I reassign one value, the other that was created from the first value will remain unchanged. This is the result of memory for the value type being allocated on the stack.

class Program
    {
        static void Main(string[] args)
        {
            decimal TwoAndaHalf = 2.5M;
            decimal CopyTwoAndAHalf = TwoAndaHalf;
            Console.WriteLine(TwoAndaHalf);
            Console.WriteLine(CopyTwoAndAHalf);

            CopyTwoAndAHalf = 3.5M;
            Console.WriteLine(TwoAndaHalf); //TwoAndaHalf = 2.5
            Console.WriteLine(CopyTwoAndAHalf); //CopyTwoAndAHalf = 3.5
            //Value types are created on the stack
            //and reference different portions of memory allocation.
        }
    }

What are the implications on Runtime?

One might also think that because the two Point properties are integer values, then they might be considered value types. Not so, the storage locations associated with these properties are always on the long-term heap.

Another item that I looked into was what is the difference in how the two data types are dealt with during their disposal. If a value type, then when the variable goes out of scope because the method in which it was defined has finished executing, the value is discarded from the stack. If it is a reference type, then the object will be collected eventually through the common language runtime's (CLR's) Garbage Collection. For more about Garbage Collection check out this link. 

Thanks and once again, I hope you found something of value in this post.

Posted on by:

shoupn profile

Nick Shoup

@shoupn

GIS Developer, outdoor enthusiast, cryptocurrency/blockchain enthusiast, father, and husband. I really just want to share my passion for coding with others.

Discussion

markdown guide