{"id":1367,"date":"2012-07-11T00:00:00","date_gmt":"2012-07-11T00:00:00","guid":{"rendered":"https:\/\/test.simple-talk.com\/uncategorized\/net-memory-management-basics\/"},"modified":"2021-05-17T18:36:14","modified_gmt":"2021-05-17T18:36:14","slug":"net-memory-management-basics","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/development\/dotnet-development\/net-memory-management-basics\/","title":{"rendered":".NET Memory Management Basics"},"content":{"rendered":"<div id=\"pretty\">\n<div class=\"note\">\n<p class=\"note\">This article is taken from Chapter 1 of the book <a href=\"http:\/\/www.simple-talk.com\/books\/.net-books\/under-the-hood-of-.net-memory-management\/\">&#8216;Under the Hood of .NET Memory Management&#8217; <\/a>&#160;by Chris Farrell and Nick Harrison. This can be downloaded as a free PDF eBook from&#160; <a href=\"http:\/\/www.simple-talk.com\/books\/.net-books\/under-the-hood-of-.net-memory-management\/\">here<\/a><\/p>\n<\/div>\n<h2>Overview <\/h2>\n<p class=\"start\">If you think about it, an application is made up of two things; the code itself, and the data that stores the state of the application during execution. When a .NET application runs, four sections of memory (heaps) are created to be used for storage: <\/p>\n<ul>\n<li>The <strong>Code Heap<\/strong> stores the actual native code instructions after they have been Just in Time Compiled (<strong>JITed<\/strong>).  <\/li>\n<li>The <strong>Small Object Heap<\/strong> (<strong>SOH<\/strong>) stores allocated objects that are less than 85K in size  <\/li>\n<li>The <strong>Large Object Heap<\/strong> (<strong>LOH<\/strong>)stores allocated objects <em>greater<\/em> than 85K (although there are some exceptions, which we won&#8217;t discuss in this overview article but is in <a href=\"http:\/\/www.simple-talk.com\/books\/.net-books\/under-the-hood-of-.net-memory-management\/\">chapter 2 <\/a>of the book)  <\/li>\n<li>Finally, there&#8217;s the <strong>Process Heap<\/strong>, but let&#8217;s not go there just yet <\/li>\n<\/ul>\n<p>Everything on a heap has an address, and these addresses are used to track program execution and application state changes. <\/p>\n<p>Applications are usually written to encapsulate code into methods and classes, so .NET has to keep track of chains of method calls as well as the data state held within each of those method calls. When a method is called, it has its own cocooned environment where any data variables it creates exist only for the lifetime of the call. A method can also get data from globals\/static objects, and from the parameters passed to it. <\/p>\n<p>In addition, when one method calls another, the local state of the calling method (variables, parameters) has to be remembered while the method to be called executes. Once the called method finishes, the original state of the caller needs to be restored so that it can continue executing. <\/p>\n<p>To keeping track of everything (and there is often quite a lot of &#8220;everything&#8221;), .NET maintains a stack data structure, which it uses to track the state of an execution thread and all the method calls made. <\/p>\n<h2>Stack <\/h2>\n<p>So the stack is used to keep track of a method&#8217;s data from every other method call. When a method is called, .NET creates a container (a stack frame) that contains all of the data necessary to complete the call, including parameters, locally declared variables and the address of the line of code to execute after the method finishes. For every method call made in a call tree (i.e. one method that calls another, which calls another&#8230; etc.), stack containers are stacked on top of each other. When a method completes, its&#8217; container is removed from the top of the stack and the execution returns to the next line of code within the calling method (with its own stack frame). The frame at the top of the stack is always the one used by the current executing method. <\/p>\n<p>Using this simple mechanism, the state of every method is preserved in between calls to other methods, and they are all kept separate from each other. <\/p>\n<p>In Listing 1 <code>Method1<\/code> calls <code>Method2<\/code> , passing an <code>int<\/code> as a parameter. <\/p>\n<pre>1 void Methodl ()\n2 {\n3&#160;&#160;&#160;&#160; Method2(12);\n4&#160;&#160;&#160;&#160; Console.WriteLine(\"Goodbye\");\n5 }\n6 void Method2(int testData)\n7 {\n8&#160;&#160;&#160;&#160; int multiplier=2;\n9&#160;&#160;&#160;&#160; Console.WriteLine(\"Value is \" + testData.ToString());\n10&#160;&#160;&#160; Method3|(testData * multplier) ;\n11 }\n12 void Method3(int data)\n13 {\n14&#160;&#160;&#160; Console.WriteLine(\"Double \" + testData.ToString());\n15 }<\/pre>\n<p class=\"caption\">Listing 1: Simple Method call chain <\/p>\n<p>To call <code>Method2<\/code> the application thread needs first to record an execution return address which will be the next line of code after the call to <code>Method2<\/code> . When <code>Method2<\/code> has completed execution, this address is used to call the next line of code in <code>Method1<\/code> , which is line 4. The return address is therefore put on the Stack. <\/p>\n<p>Parameters to be passed to <code>Method2<\/code> are also placed on the stack. Finally we are ready to jump our execution to the code address for <code>Method2<\/code> . <\/p>\n<p>If we put a break point on line 13 the stack would look something like this: <\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1523-img36.gif\" alt=\"1523-img36.gif\" \/><\/p>\n<p class=\"caption\">&#160;Figure 1: Example of a Stack Frame <\/p>\n<p>Obviously this is a huge simplification, and addresses wouldn&#8217;t use code line numbers for return addresses, but hopefully you get the idea. <\/p>\n<p>In&#160; Figure 1, stack frames for Methods 1,2 and 3 have been stacked on top of each other, and at the moment the current stack frame is <code>Method3<\/code> , which is the current executing method. When <code>Method3<\/code> completes execution, it&#8217;s stack frame is removed, the execution point moves to <code>Method2<\/code> (line 9 in Listing 1), and execution continues. <\/p>\n<p>A nice simple solution to a complex problem, but don&#8217;t forget if your application has multiple threads, then each thread will have its&#8217; own stack. <\/p>\n<h2>Heap <\/h2>\n<p>So where does the Data Heap come into it? Well, the stack can store variables that are the primitive data types defined by .NET. These include the following types:- <\/p>\n<ul>\n<li>Byte  <\/li>\n<li>SByte  <\/li>\n<li>Int16  <\/li>\n<li>Int32  <\/li>\n<li>Int64  <\/li>\n<li>UInt16  <\/li>\n<li>UInt32  <\/li>\n<li>UInt64  <\/li>\n<li>Single  <\/li>\n<li>Double  <\/li>\n<li>Boolean  <\/li>\n<li>Char  <\/li>\n<li>Decimal  <\/li>\n<li>IntPtr  <\/li>\n<li>UIntPtr  <\/li>\n<li>Structs <\/li>\n<\/ul>\n<p>These are primitive data types and part of <strong>Common Type System<\/strong> (<strong>CTS<\/strong>) natively understood by all NET language compilers, and are collectively called <strong>Value Types<\/strong>. Any of these data types or struct definitions are usually stored on the stack. <\/p>\n<p>On the other hand, instances of everything you have defined, including: <\/p>\n<ul>\n<li>Classes  <\/li>\n<li>Interfaces  <\/li>\n<li>Delegates  <\/li>\n<li>Strings  <\/li>\n<li>Instances of &#8220;object&#8221; <\/li>\n<\/ul>\n<p>&#8230; are all referred to as &#8220;reference types&#8221;, and are stored on the heap (the SOH or LOH, depending on their size). <\/p>\n<p>When an instance of a reference type is created (usually involving the <code>new<\/code> keyword), only an <em>object reference<\/em> is stored on stack. The actual instance itself is created on the heap, and its&#8217; address held on the stack. <\/p>\n<p>Consider the following code: <\/p>\n<pre>1 void Method1() \n2 { \n3&#160;&#160;&#160;&#160;&#160; MyClass myObj=new MyClass(); \n4&#160;&#160;&#160;&#160;&#160; Console.WriteLine(myObj.Text); \n5 }\n<\/pre>\n<p class=\"caption\">Listing 2: Code example using a reference type <\/p>\n<p>In Listing 2<strong> .<\/strong> a new instance of the class <code>MyClass<\/code> is created within the <code>Method1<\/code> call. <\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1523-img38.gif\" alt=\"1523-img38.gif\" \/><\/p>\n<p class=\"caption\">&#160;Figure 2: Object Reference from Stack to Heap <\/p>\n<p>As we can see in&#160; Figure 2, To achieve this, .NET has to create the object on the memory heap, determine its address on the heap (or object reference), and place that object reference within the stack frame for <code>Method1<\/code> . As long as <code>Method1<\/code> is executing, the object allocated on the heap will have a reference held on the stack. When <code>Method1<\/code> completes, the stack frame is removed (along with the object reference), leaving the object without a reference. <\/p>\n<p>We will see later how this affects memory management and the garbage collector. <\/p>\n<h3>More on Value and Reference Types <\/h3>\n<p>The way in which variable assignment works differs between reference and value types. <\/p>\n<p>Consider the following code: <\/p>\n<pre>1 void ValueTest() \n2 { \n3&#160;&#160;&#160;&#160;&#160; int v1=12; \n4&#160;&#160;&#160;&#160;&#160; int v2=22; \n5&#160;&#160;&#160;&#160;&#160; v2=v1; \n6&#160;&#160;&#160;&#160;&#160; Console.Writeline(v2); \n7 }<\/pre>\n<p class=\"caption\">Listing 3: Assignment of Value Types <\/p>\n<p>If a breakpoint was placed at line 6, then the stack\/heap would look like this : <\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1523-img3A.gif\" alt=\"1523-img3A.gif\" \/><\/p>\n<p class=\"caption\">&#160;Figure 3: Stack example of value type assignment <\/p>\n<p>There are two separate integers on the stack both with the same value. <\/p>\n<p>Notice there are two stack variables, <code>v1<\/code> and <code>v2<\/code> , and all the assignment has done is assign the same value to both variables. <\/p>\n<p>Let&#8217;s look at a similar scenario, this time using a class I have defined, <code>MyClass<\/code> , which is (obviously) a reference type: <\/p>\n<pre>1 void RefTest() \n2 { \n3&#160;&#160;&#160;&#160;&#160; MyClass v1=new MyClass(12); \n4&#160;&#160;&#160;&#160;&#160; MyClass v2=new MyClass(22); \n5&#160;&#160;&#160;&#160;&#160; v2=v1; \n6&#160;&#160;&#160;&#160;&#160; Console.Writeline(v2.Value); \n7 }<\/pre>\n<p class=\"caption\">Listing 4: Assignment with Reference Types <\/p>\n<p>Placing a break point on line 5 in Listing 4 would see two <code>MyClass<\/code> instances allocated onto the heap: <\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1523-img3C.gif\" alt=\"1523-img3C.gif\" \/><\/p>\n<p class=\"caption\">&#160;Figure 4: Variable Assignment with Reference Types <\/p>\n<p>On the other hand, letting execution continue, and allowing <code>v1<\/code> to be assigned to <code>v2<\/code> the execution at line 6 in Listing 4, would show a very different heap: <\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1523-img3E.gif\" alt=\"1523-img3E.gif\" \/><\/p>\n<p class=\"caption\">&#160;Figure 5: Variable Assignment with Reference Types 2 <\/p>\n<p>Notice how, in&#160; Figure 5, both object pointers are referencing only the one class instance after the assignment. Variable assignment with reference types makes the object pointers on the stack the same, and so they both point to the same object on the heap. <\/p>\n<h3>Passing Parameters <\/h3>\n<p>When you pass a value type as a parameter, all you actually pass to the calling method is a copy of the variable. Any changes that are made to the passed variable within the method call are isolated to the method. <\/p>\n<p>Having copies of value types on the stack isn&#8217;t usually a problem, unless the value type is large, as can be the case with structs. While structs are value types, and as such are also allocated onto the stack, they are also, by their nature, programmer-definable structures, and so they can get pretty large. When this is the case, and particularly if they are passed as parameters between method calls, it can be a problem for your application. Having multiple copies of the same struct created on the stack creates extra work in copying the struct each time. This might not seem like a big deal, but when magnified within a high iteration loop, it can cause a performance issue. <\/p>\n<p>One way around this problem is to pass specific value types by reference. This is something you would do anyway if you wanted to allow direct changes to the value of a passed variable inside a method call. <\/p>\n<p>Consider the following code: <\/p>\n<pre>void Method1() \n{\n&#160;&#160;&#160; int v1=22;\n&#160;&#160;&#160; Method2(v1);\n&#160;&#160;&#160; Console.WriteLine(\"Method1 = \" + v1.ToString());\n&#160;} \nvoid Method2(int v2) \n{\n&#160;&#160;&#160; v2=12;\n&#160;&#160;&#160; Console.WriteLine(\"Method2 = \" + v2.ToString()); \n}<\/pre>\n<p class=\"caption\">Listing 5: Passing parameters by value <\/p>\n<p>Once <code>Method1<\/code> completes we would see the following output: <\/p>\n<pre>Method 2 = 12 \nMethod 1 = 22<\/pre>\n<p class=\"caption\">Listing 6: Output from a parameter passed by value <\/p>\n<p>Because parameter <code>v1<\/code> was passed to <code>Method2<\/code> by value, any changes to it within the call don&#8217;t affect the original variable passed. That&#8217;s why the first output line shows <code>v2<\/code> as being 12. The second output line demonstrates that the original variable remains unchanged. <\/p>\n<p>Alternatively, by adding a <code>ref<\/code> instruction to both the method and the calling line, variables can be passed by reference (Listing 7). <\/p>\n<pre>void Method1() \n{ \n&#160;&#160;&#160; int v1=22;\n&#160;&#160;&#160; Method2(ref v1);\n&#160;&#160;&#160; Console.WriteLine(\"Method1 = \" + v1.ToString());\n&#160;}\n&#160;void Method2(ref int v2) \n{ \n&#160;&#160;&#160; v2=12; \n&#160;&#160;&#160; Console.WriteLine(\"Method2 = \" + v2.ToString()); \n}<\/pre>\n<p class=\"caption\">Listing 7: Passing parameters by reference <\/p>\n<p>Once <code>Method1<\/code> completes, we would see the following output (Listing 8): <\/p>\n<pre>Method 2 = 12 \nMethod 1 = 12<\/pre>\n<p class=\"caption\">Listing 8: Output from a parameter passed by reference <\/p>\n<p>Notice both outputs display &#8220;12&#8221;, demonstrating that the original passed value was altered. <\/p>\n<h3>Boxing and Unboxing <\/h3>\n<p>Let&#8217;s now talk about that topic you always get asked about in interviews, boxing and unboxing. It&#8217;s actually really easy to grasp, and simply refers to the extra work required when your code causes a value type (e.g. <code>int<\/code> , <code>char<\/code> etc) to be allocated on the heap rather than the stack. As we saw earlier, allocating onto the heap requires more work, and so is less efficient. <\/p>\n<p>The classic code example of boxing and unboxing looks something like this: <\/p>\n<pre>1 \/\/ Integer is created on the Stack \n2 int stackVariable=12; \n3 \/\/ Integer is created on the Heap = Boxing \n4 object boxedObject= stackVariable; \n5 \/\/ Unboxing \n6 int unBoxed=(int)boxedObject;<\/pre>\n<p class=\"caption\">Listing 9: Classic Boxing and Unboxing example <\/p>\n<p>In Listing 9 an integer is declared and allocated on the stack because it&#8217;s a value type (line 2). It&#8217;s then assigned to a new object variable (boxed) which is a reference type (line 4), and so a new object is allocated on the heap for the integer. Finally, the integer is unboxed from the heap and assigned to an integer stack variable (line 6). <\/p>\n<p>The bit that confuses everyone is &#8220;<em>why you would ever do this?<\/em>&#8220;; it makes no sense. <\/p>\n<p>The answer to that is that you can cause boxing of value types to occur very easily without ever being aware of it. <\/p>\n<pre>1 int i=12; \n2 ArrayList lst=new ArrayList(); \n3 \/\/ ArrayList Add method has the following signature \n4 \/\/ int Add(object value) \n5 lst.Add(i); \/\/ Boxing occurs automatically \n6 int p=(int)lst[0]; \/\/ Unboxing occurs<\/pre>\n<p class=\"caption\">Listing 10: Boxing a value type <\/p>\n<p>Listing 10 demonstrates how boxing and unboxing can sneakily occur, and I bet you&#8217;ve written similar code at some point. Adding an integer (value type) to the <code>ArrayList<\/code> will cause a boxing operation to occur because, to allow the array list to be used for all types (value and reference), the <code>Add<\/code> method takes an object as a parameter. So, in order to add the integer to the <code>ArrayList<\/code> , a new object has to be allocated onto the heap. <\/p>\n<p>When the integer is accessed on line 6, a new stack variable &#8220;p&#8221; is created, and its&#8217; value set to the same value as the first integer in the <code>ArrayList<\/code> . <\/p>\n<p>In short, a lot more work is going on than is necessary, and if you were doing this in a loop with thousands of integers then performance would be significantly slower. <\/p>\n<h2>More on the Heap <\/h2>\n<p>Now that we&#8217;ve had our first look at the heap(s), let&#8217;s dig a little deeper. <\/p>\n<p>When a reference type is created (<code>class<\/code> , <code>delegate<\/code> , <code>interface<\/code> , <code>string<\/code> or <code>object<\/code> ), it&#8217;s allocated onto the heap. Of the 4 heaps we&#8217;ve seen so far, .NET uses two of them to manage large objects (anything over 85K) and small objects differently. They are known as managed heaps. <\/p>\n<p>To make it the worry-free framework that it is, .NET doesn&#8217;t let you allocate objects directly onto the heap like C\/C++ does. Instead, it manages object allocations on your behalf, freeing you from having to deallocate everything you create. By contrast, if a C++ developer didn&#8217;t cleanup their allocated objects, then the application would just continually leak memory. <\/p>\n<p>To create an object, all you need to do is use the <code>new<\/code> keyword; .NET will take care of creating, initializing and placing the object on the right heap, and reserving any extra memory necessary. After that you can pretty much forget about that object, because you don&#8217;t have to delete it when you&#8217;re finished with it. <\/p>\n<p>Naturally, you can help out by setting objects to null when you&#8217;ve finished with them, but most of the time, when an object goes out of scope, it will be cleaned up automatically. <\/p>\n<h3>Garbage Collection <\/h3>\n<p>To achieve this automatic cleanup, .NET uses the famous (or perhaps infamous ) <strong>Garbage Collector<\/strong> (<strong>GC<\/strong>). All the GC does is look for allocated objects on the heap that aren&#8217;t being referenced by anything. The most obvious source of references, as we saw earlier, is the stack. Other potential sources include: <\/p>\n<ul>\n<li>Global\/Static object references  <\/li>\n<li>CPU registers  <\/li>\n<li>Object Finalization references (more later)  <\/li>\n<li>Interop references (.NET objects passed to COM\/API calls)  <\/li>\n<li>Stack references <\/li>\n<\/ul>\n<p>Collectively, these are all called root references or GC Roots. <\/p>\n<p>As well as root references, an object can also be referenced by other objects. Imagine the classic <code>Customer<\/code> class, which usually has a collection storing <code>Order<\/code> classes. <\/p>\n<p>When an Order is added to the order collection the collection itself then holds a reference to the added order. If the instance of the customer class had a stack reference to it as well, it would have the following references: <\/p>\n<ul>\n<li>A Stack-based root reference for a <code>Customer<\/code> containing:\n<ul>\n<li>AA reference to the orders <code>ArrayList<\/code> collection, which contains:\n<ul>\n<li>References to <code>order<\/code> objects. <\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1523-img40.gif\" alt=\"1523-img40.gif\" \/><\/p>\n<p class=\"caption\">&#160;Figure 6: Reference tree for a typical scenario <\/p>\n<p class=\"caption\">&#160;Figure 6 shows the basic reference tree, with a global root reference to a <code>Customer<\/code> class that, in turn, holds a collection of <code>Order<\/code> classes. <\/p>\n<p>This is important because if an object doesn&#8217;t ultimately have a root reference then it can&#8217;t actually be accessed by code, and so it is no longer in use, and can be removed. As you can see above, a large number of objects can be maintained by just a single root reference, which is both good and bad, as we&#8217;ll see later. <\/p>\n<h3>Inspection and Collection <\/h3>\n<p>To make sure objects which are no longer in use are cleared away, the Garbage Collector simply gets a list of all root references and, for each one, moves along it&#8217;s reference tree &#8220;marking&#8221; each object found as being in use (we&#8217;ll come back to what that means in just a moment). Any objects not marked as being in use, or &#8220;live&#8221;, are free to be &#8220;collected&#8221; (which we&#8217;ll also come back to later). <\/p>\n<p>A simplified version would look something like this:&#160;  <\/p>\n<pre>void Collect()\n{ List gcRoots=GetAllGCRoots();\n&#160; foreach (objectRef root in gcRoots) \n&#160; { \n&#160;&#160;&#160;&#160; Mark(root); \n&#160; } \n&#160; Cleanup(); \n}<\/pre>\n<p class=\"caption\">Listing 11: Simplified GC Collection in pseudo code&#160;  <\/p>\n<p>The <strong>Mark<\/strong> operation adds an object to an &#8220;object still in use&#8221; list (if it&#8217;s not already in there), and then iterates through all of its child object references, marking each one in turn. The result is a list of all objects currently in memory that are still in use. <\/p>\n<pre>VVoid Mark(objectRef o)\n{ \n&#160;&#160;&#160; if (!InUseList.Exists(o)) \n&#160;&#160;&#160; {\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; InUseList.Add(o); \n&#160;&#160;&#160;&#160;&#160;&#160;&#160; List refs=GetAllChildReferences(o);\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; foreach (objectRef childRef in refs) \n&#160;&#160;&#160;&#160;&#160;&#160;&#160; { \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Mark(childRef);\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; }\n&#160;&#160;&#160; } \n}<\/pre>\n<p class=\"caption\">Listing 12: Simplified GC Mark operation in pseudo code&#160;  <\/p>\n<p>Once that list is compiled, the GC can then go about cleaning up the heaps, and we&#8217;ll now go through how the <strong>Cleanup<\/strong> operation works differently for both the SOH and LOH. In both cases, the result of a cleanup operation is a resetting of the &#8220;object still in use&#8221; list, ready for the next collection. <\/p>\n<h3>SOH Cleanup &#8211; Heap Compaction <\/h3>\n<p>Garbage collection of the Small Object Heap (SOH) involves compaction. This is because the small object heap is a contiguous heap where objects are allocated consecutively on top of each other. When compaction occurs, marked objects are copied over the space taken up by unmarked objects, overwriting those objects, removing any gaps, and keeping the heap contiguous; this process is known as Copy Collection. The advantage of this is that heap fragmentation (i.e. unusable memory gaps) is kept to a minimum. The main disadvantage is that compaction involves copying chunks of memory around, which requires CPU cycles and so, depending on frequency, can cause performance problems. What you gain in efficient allocation you could lose in compactions costs. <\/p>\n<h3>LOH Sweeping &#8211; Free Space Tracking <\/h3>\n<p>The Large Object Heap (LOH) isn&#8217;t compacted, and this is simply because of the time it would take to copy large objects over the top of unused ones. Instead, the LOH keeps track of free and used space, and attempts to allocate new objects into the most appropriately-sized free slots left behind by collected objects. <\/p>\n<p>As a result of this, the LOH is prone to fragmentation, wherein memory gaps are left behind that can only be used if large objects (i.e. &gt;85K) of a similar or smaller size to those gaps are subsequently allocated. <\/p>\n<p>For more detail of&#160; these managed heaps, you&#8217;ll have to look in <a href=\"http:\/\/www.simple-talk.com\/books\/.net-books\/under-the-hood-of-.net-memory-management\/\">chapter 2 of the book<\/a> <\/p>\n<h2>Static objects <\/h2>\n<p>I&#8217;ve already mentioned static\/global objects as a source of root references, but let&#8217;s now look at that topic in a bit more detail, and with some more background. <\/p>\n<p>Marking a class member as static makes it a class-specific, rather than instance-specific, object. With using non-static members, you would need to declare an instance of the necessary class before you could access its members. On the other hand Static members can be accessed directly by just using the class name.&#160;  <\/p>\n<pre>class Person \n{\n&#160;&#160;&#160; public int Age=0;\n&#160;&#160;&#160; public static MaxAge=120; \n}<\/pre>\n<p class=\"caption\">Listing 13: Example of a static member variable <\/p>\n<p>Listing 13 shows both an instance variable (<code>Age<\/code> ) and a static variable (<code>MaxAge<\/code> ) on a <code>Person<\/code> class. The static variable is being used as a piece of general data across the range of <code>Person<\/code> instances (people aren&#8217;t usual older than 120), whereas the instance variable is specific to an instance of the class i.e. an individual person. <\/p>\n<p>To access each member, you would need to write the following code: <\/p>\n<pre>Person thisPerson=new Person();\nthisPerson.Age=121; \n\nff (thisPerson.Age&gt;Person.MaxAge) \n{\n&#160;&#160;&#160;&#160; \/\/ Validation Failure \n}<\/pre>\n<p class=\"caption\">Listing 14: Accessing Statics <\/p>\n<p>In Listing 14, an instance of a <code>Person<\/code> is created, and its <em>only<\/em> via the instance variable that the <code>Age<\/code> member is accessible, whereas <code>MaxAge<\/code> is available as a kind of global member on the <code>Person<\/code> type itself . <\/p>\n<p>In C#, statics are often used to define global variables. <\/p>\n<h3>Static Methods and Fields <\/h3>\n<p>When you mark a method, property, variable or event as static, the runtime creates a global instance of each one soon after the code referencing them is loaded &amp; used. <\/p>\n<p>Static members don&#8217;t need to be created using the <code>new<\/code> keyword, but are accessed using the name of the class they were defined within. They are accessible by all threads in an app domain (unless they are marked with the <code>[<\/code> <code>ThreadStatic<\/code> <code>] <\/code>attribute, which I&#8217;ll come back to in a moment), and are never garbage collected because they essentially <em>are<\/em> root references in themselves. <\/p>\n<p>Statics are a common and enduring source of root references, and can be responsible for keeping objects loaded in memory for far longer than would otherwise be expected. <\/p>\n<p>Listing 15 shows the declaration of a static object and its initialization within a static constructor. Once loaded, the static constructor will execute, creating a static instance of the Customer class, and a reference will be held to an instance of the <code>Customer<\/code> class for the duration of the application domain (or the thread, if the reference is marked <code>[<\/code> <code>ThreadStatic<\/code> <code>]<\/code> ). <\/p>\n<pre>public class MyData\n{\n&#160; public static Customer Client;\n&#160; public static event EventType OnOrdersAdded;\n&#160; static MyData()\n&#160; {\n&#160;&#160;&#160;&#160; \/\/ Initialize \n&#160;&#160;&#160;&#160; Client=new Customer(); \n&#160; } \n}<\/pre>\n<p class=\"caption\">Listing 15: Static Reference example&#160;  <\/p>\n<p>It&#8217;s also worth remembering that any classes that subscribe to static events will remain in memory until the event subscription is removed, or the containing app domain finishes. <\/p>\n<p>Static collections can also be a problem, as the collection itself will act as a root reference, holding all added objects in memory for the lifetime of the app domain. <\/p>\n<h3>Thread Statics <\/h3>\n<p>Sometimes you may want to prevent multiple threads accessing a common set of statics. To do this, you can add the <code>[<\/code> <code>ThreadStatic<\/code> <code>]<\/code> attribute to the member, and create multiple static instances of that member &#8211; one for each isolated thread (one instance per thread). See Listing 16. <\/p>\n<pre>[ThreadStatic]\npublic static int NumberofThreadHits=0;<\/pre>\n<p class=\"caption\">Listing 16: Marking a member [ThreadStatic] <\/p>\n<h2>Summary <\/h2>\n<p>Ok, we&#8217;ve covered the basics of stacks, heaps, garbage collecting and referencing, and how they all hang together inside the .NET framework. Some of the material we&#8217;ve covered in this article has been deliberately simplified so that you get a good &#8220;in principal&#8221; understanding without being buried under the fine detail.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>.NET memory management is designed so that the programmer is freed from the chore of consciously having to allocate and dispose of memory resources. It is optimized to work best with the most common patters of usage. However, the more conscious you become of scalability and performance, the more useful an understanding of NET memory management becomes.&hellip;<\/p>\n","protected":false},"author":221880,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143538],"tags":[4143,4229,4242,4178,4179],"coauthors":[],"class_list":["post-1367","post","type-post","status-publish","format-standard","hentry","category-dotnet-development","tag-net","tag-net-framework","tag-basics","tag-bi","tag-source-control"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/1367","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/221880"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=1367"}],"version-history":[{"count":5,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/1367\/revisions"}],"predecessor-version":[{"id":91102,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/1367\/revisions\/91102"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=1367"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=1367"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=1367"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=1367"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}