{"id":839,"date":"2010-03-24T00:00:00","date_gmt":"2010-03-24T00:00:00","guid":{"rendered":"https:\/\/test.simple-talk.com\/uncategorized\/investigating-net-memory-management-and-garbage-collection\/"},"modified":"2021-05-17T18:36:34","modified_gmt":"2021-05-17T18:36:34","slug":"investigating-net-memory-management-and-garbage-collection","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/development\/dotnet-development\/investigating-net-memory-management-and-garbage-collection\/","title":{"rendered":"Investigating .NET Memory Management and Garbage Collection"},"content":{"rendered":"<h2><span lang=\"EN-GB\">Introduction<\/span><\/h2>\n<p class=\"start\">We will be looking into the world of managed memory In this article. It is a world in that part of the CLR where the garbage collector is king. We will consider what a memory leak is, how the garbage collector works and why it cannot always free memory; we will then, finally and most excitingly, reveal how to examine both memory and specific objects using <strong>Son of Strike (SOS).<\/strong><\/p>\n<h2><span lang=\"EN-GB\">What is a memory leak?<\/span><\/h2>\n<p><span lang=\"EN-GB\">At its most basic, a memory leak happens when memory has been allocated and, for whatever reason, that memory is not freed when the application has finished using it. In a .Net language, you allocate memory by creating an object and you free the memory by allowing the reference to that object to go out of scope. Simply put:<\/span><\/p>\n<pre>void MethodName()\r\n{\r\n                Object o = new Object(); \r\n\/\/Create a new Object and store a reference to it as o\r\n                DoSomethingWith(o);  \r\n\/\/Use the new Object by passing the reference to o\r\n                o = null;            \r\n\/\/Lose the reference to the new Object, it is now eligible for freeing\r\n}                                       \r\n\/\/o is now out of scope so can be freed<\/pre>\n<p><span lang=\"EN-GB\">When &#8220;o&#8221; goes out of scope, the garbage collector can examine the object to see if it has any references; if nothing is referencing the object, it can be freed. If the &#8220;<strong>DoSomethingWith<\/strong>&#8221; method caused a reference to be kept to &#8220;<strong>o<\/strong>&#8221; then, when the garbage collector checked to see if it was being used, there would still be a reference and so it would not be able to free the memory.<\/span><\/p>\n<p><span lang=\"EN-GB\">I have mentioned the word \u2018reference\u2019 a few times; When you call <strong>new,<\/strong> you don\u2019t actually get the object returned, but a reference to the new object which is created in the heap space.<\/span><\/p>\n<p><span lang=\"EN-GB\">This can be quite a dry subject, so just for fun let\u2019s take a look at the MSIL for this:<\/span><\/p>\n<pre>.method private hidebysig instance void  MethodName() cil managed\r\n{\r\n  \/\/ Code size       18 (0x12)\r\n  .maxstack  2\r\n  .locals init ([0] object o)\r\n  IL_0000:  nop\r\n  IL_0001:  newobj     instance void [mscorlib]System.Object::.ctor()\r\n  IL_0006:  stloc.0\r\n  IL_0007:  ldarg.0\r\n  IL_0008:  ldloc.0\r\n  IL_0009:  call instance void leak.SampleClass::DoSomethingWith(object)\r\n  IL_000e:  nop\r\n  IL_000f:  ldnull\r\n  IL_0010:  stloc.0\r\n  IL_0011:  ret\r\n} \/\/ end of method SampleClass::MethodName<\/pre>\n<p><span lang=\"EN-GB\">We can see here that <strong>IL_0001<\/strong> Calls the &#8220;newobj&#8221; command and, according to MSDN (<a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/system.reflection.emit.opcodes.newobj.aspx\">MSDN .NET OpCodes &#8211; Newobj Field<\/a>), this creates a new object and puts a reference onto the &#8220;evaluation stack&#8221;. Then the next command <strong>IL_006 stloc.0<\/strong> takes the value on the top of the &#8220;evaluation stack&#8221; and stores it in the local variable list. We see that we don\u2019t actually get the object but just a reference to it; in other words the memory address that the object is sitting in.<\/span><\/p>\n<p><span lang=\"EN-GB\">As I mentioned previously, as long as <strong>DoSomethingWith<\/strong> does not store a reference to the object, when it gets to the end of this method and goes out of scope, the reference will be lost and the garbage collector can free the memory. In this case, therefore, there is no memory leak.<\/span><\/p>\n<h3><span lang=\"EN-GB\">How do I know if I have a memory leak?<\/span><\/h3>\n<p><span lang=\"EN-GB\">If you have a true memory leak then you may eventually start getting <strong>OutOfMemory<\/strong> (OOM) exceptions after a while, if the problem is severe enough. If you want to be pro-active you can monitor the application using the Performance Monitor <strong>PerfMon,<\/strong> rather than wait for OOMs . If you monitor the &#8220;<em><strong>Process<\/strong><\/em>&#8221; and &#8220;<strong><em>Private Bytes<\/em><\/strong>&#8221; counters for your specific process, you will see the increase in the amount of memory used and how it happens. Typically you should also look at the &#8220;<em><strong>.Net CLR Memory\\# Bytes In All Heaps<\/strong><\/em>&#8221; for your process, which should increase in-line with private bytes if you have a standard memory leak.<\/span><\/p>\n<p><span lang=\"EN-GB\">When you are monitoring your application, you might come across a memory hog which uses a lot of memory but does free it when it is finished. The method of troubleshooting these hogs is exactly the same as finding memory leaks, you just need to do the analysis when the objects are live and before the garbage collector does its thing and removes the evidence.<\/span><\/p>\n<h3><span lang=\"EN-GB\">What does it matter if an application has a problem with memory?<\/span><\/h3>\n<p><span lang=\"EN-GB\">The quick answer is that your application will run more slowly. The longer answer is this: Ideally there should be enough available every time your application tries to allocate memory. If there isn\u2019t, then either you will get an OOM exception which is often critical or, in the best case, the garbage collector needs to go to work to move other objects around. This will use up precious processing power and also delay your request.<\/span><\/p>\n<h3><span lang=\"EN-GB\">Isn\u2019t it impossible to get memory leaks in .net?<\/span><\/h3>\n<p><span lang=\"EN-GB\">It is true that the whole point of the garbage collector is that it is there to stop you having to worry about allocating and freeing memory. This was a real bugbear in languages such as C and C++, but a garbage collector can only work with what you give it. If you keep a reference to an object that you don\u2019t need, you are stopping the GC from freeing it. Although the GC keeps a reference to the object, so it can never be lost or re-allocated, it is not possible to free it as long as the application keeps its own reference.<\/span><\/p>\n<h2><span lang=\"EN-GB\">SOS Commands<\/span><\/h2>\n<p><span lang=\"EN-GB\">Examining the objects in memory is simple with SOS. Apart from the command to actually examine individual objects &#8220;<strong>!DumpObject<\/strong>&#8220;, there are only two commands you ever have to use, &#8220;<strong>!GCRoot<\/strong>&#8221; which shows what is holding a reference to an object and &#8220;<strong>!DumpHeap<\/strong>&#8221; which shows what is currently in memory.<\/span><\/p>\n<p><span lang=\"EN-GB\">When you have an application that is either leaking or is a memory hog and you want to make it better, you have to know two things:<\/span><\/p>\n<ol style=\"margin-top: 5px; padding-top: 0px;\">\n<li><span lang=\"EN-GB\">What objects are using the memory<\/span><\/li>\n<li><span lang=\"EN-GB\"> What creates and keeps a reference to those objects<\/span><\/li>\n<\/ol>\n<p><span lang=\"EN-GB\">Once you know these two things, you can use your ninja coding skills to change the way the memory is used, perhaps by removing them from a list once they are no longer needed or freeing them in a parent objects destructor or Dispose method.<\/span><\/p>\n<h3><span lang=\"EN-GB\">DumpHeap<\/span><\/h3>\n<p><span lang=\"EN-GB\">This command has two parameters which we will cover here &#8220;-<strong>stat<\/strong>&#8221; and &#8220;<strong>-type<\/strong>&#8221; (or &#8220;<strong>-mt<\/strong>&#8220;). The first key to finding out what objects are hanging around is to open a debugger, load up Son of Strike (SOS) and run <strong>&#8220;!DumpHeap \u2013stat.<\/strong> (If this is completely foreign to you, and you are unsure how to get to this point, then take a look at <a href=\"https:\/\/www.red-gate.com\/simple-talk\/dotnet\/net-framework\/net-debugging-dont-give-me-none-of-your-vs\/\">.NET Debugging: Don\u2019t give me none of your VS<\/a>). The command finds all the objects, groups them by type and the orders them by how much memory the cumulative total of all objects of that grouped type. I have included a sample application in the .ZIP file attached to this article (See the speech-bubble at the head of the article). Feel free to follow along using it. The first example is of a method that creates a List and assigns a list of <strong>ArraySegments<\/strong> to it, it is a typical memory hog in that, when the method finishes, the memory will be available to be freed.<\/span><\/p>\n<p><span lang=\"EN-GB\">The output to the command &#8220;<strong>!DumpHeap \u2013stat<\/strong>&#8221; looks like:<\/span><\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/980-DumpHeap_Stat.png\" alt=\"image\" border=\"0\" \/><\/p>\n<p>Y<span lang=\"EN-GB\">ou can click on any of the screenshots in this article to see them full-size. I should point out that the screenshots are taken from an x64 machine on the CLR 4 CTP, so some things might look slightly different. The actual process and commands are the same. Certainly, where I have highlighted areas on the screenshots, these are the same as in previous versions of the .net framework. The main difference you will see if you are on an x86 machine is that the size of pointer values are 8 bytes and sometimes separated with a \u201c`&#8221; whereas the values on the x86 machines are 4 bytes.<\/span><\/p>\n<p><span lang=\"EN-GB\">The first column shows the <strong>MethodTable<\/strong> of the <strong>object type<\/strong>, the second is the count of objects, the third shows how much memory all the objects of that particular type are using, the last column is the type name. To find what it is that is using the most memory, scroll to the bottom of the list and take a look at the objects near the bottom. If you run the sample app, attach using CDB and then press the first button &#8220;Memory Intensive Operation&#8221; and wait for the dialog to display, before you click &#8220;ok&#8221; run the <strong>DumpHeap \u2013stat<\/strong> command and at the bottom of the output you get:<\/span><\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/980-DumpHeap1.png\" alt=\"image\" border=\"0\" \/><\/p>\n<p><span lang=\"EN-GB\">We see here that there are 10,000 objects of type &#8220;<span class=\"mono\">System.ArraySegment`1[[System.Byte, mscorlib]][]<\/span>&#8221; which are using up 164,080,000 bytes of memory. If we want to have a look at those 10,000 objects we can use either <strong>\u2013type<\/strong> or <strong>\u2013mt<\/strong>. The type takes the type name and <strong>\u2013mt<\/strong> takes the method table (first column), so if we do <strong>&#8220;!DumpHeap \u2013mt 000007ff00045878&#8221;<\/strong> (The method table to use might be different on your system so be sure to copy the value that is in your output). Normally you could use <strong>\u2013type<\/strong> but because of the [\u2018s and ]\u2019s in the type name it will fail.<\/span><\/p>\n<p><span lang=\"EN-GB\">If you let the output finish, which will take some time, you see a list of the 10,000 objects, the first column is the address of the specific object, the second is the method table and the third tells you the size of that specific object.<\/span><\/p>\n<p><span lang=\"EN-GB\">If you take one of the objects at random and do &#8220;<strong>!do address&#8221;<\/strong> (address is from the first column) you will see what the object looks like:<\/span><\/p>\n<p class=\"illustration\"><span lang=\"EN-GB\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/980-DumpHeap2.png\" alt=\"image\" border=\"0\" \/><\/span><\/p>\n<p><span lang=\"EN-GB\">So we now know the type of the specific object. In some cases this would be enough, but let us assume it isn\u2019t and move onto the &#8220;<strong>GCRoot<\/strong>&#8221; command. This shows how other objects are referencing an object and stopping it from being freed.<\/span><\/p>\n<h3><span lang=\"EN-GB\">GCRoot<\/span><\/h3>\n<p><span lang=\"EN-GB\">If you take the address that we passed to &#8220;<strong>!do<\/strong>&#8221; and try &#8220;<strong>!GCRoot address<\/strong>&#8220;, it will list all the objects that have a reference to your specific object. <strong>GCRoot<\/strong> searches for references, in both the stack and the heap, if a reference is on the stack then it is very likely to be garbage collected at some point so is normally fine, but if we look at the output anyway, we can see that on thread id 10 there are a number of roots, the first one shows that a <strong>list (1.1)<\/strong> has a reference to an <strong>object array (1.2)<\/strong> which references another <strong>list (1.3)<\/strong> which references our <strong>object (1.4).<\/strong><\/span><\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/980-GCRoot1.png\" alt=\"image\" border=\"0\" \/><\/p>\n<p><span lang=\"EN-GB\">In this example the root reference is <span class=\"mono\">&#8220;0000000003b844e8&#8221;<\/span> \u2013 you can have a look at this by doing <strong>&#8220;!do 0000000003b844e8&#8221;.<\/strong> (Remember to use the address that is displayed on your machine instead of this particular address).<\/span><\/p>\n<p><span lang=\"EN-GB\">Because the reference is on the stack we can find out where it was created. To do this we<\/span><\/p>\n<ul>\n<li><span lang=\"EN-GB\"><span lang=\"EN-GB\">change the current thread to thread id 10 (or whatever thread id is in your output) by doing &#8220;<strong>~10s<\/strong>&#8220;.<\/span><\/span><\/li>\n<li><span lang=\"EN-GB\">do &#8220;<strong>!CLRStack -a<\/strong>&#8221; (-a shows all variables and parameters),<\/span><\/li>\n<li><span lang=\"EN-GB\">look at all the values and search for the first instance of the object we already found to be the root:<\/span><\/li>\n<\/ul>\n<p class=\"illustration\"><span lang=\"EN-GB\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/980-CLRStack1.png\" alt=\"image\" border=\"0\" \/><\/span><\/p>\n<p><span lang=\"EN-GB\">This shows that if we have a look at <strong>the leak.MemoryIntensiveOperation.Perform<\/strong> method we can see why we have a reference to the object.<\/span><\/p>\n<p><span lang=\"EN-GB\">If we take a look at a second example, this time instead of just being a memory hog, we have a situation where a method has directly asked the garbage collector to keep a reference to an object by doing a &#8220;<strong>GCHandle.Alloc(o, GCHandleType.Pinned<\/strong>);&#8221; which creates a handle to the memory and stops it from being freed.<\/span><\/p>\n<p><span lang=\"EN-GB\">If you run the sample app under cdb and press the second button &#8220;<strong>GC Alloc<\/strong>&#8221; a few times, this perfmon shows how the private bytes increases every time I push the button and is typical in a memory leaking app, the memory constantly increases whenever a specific action occurs:<\/span><\/p>\n<p class=\"illustration\"><span lang=\"EN-GB\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/980-Perfmon1.png\" alt=\"image\" border=\"0\" \/><\/span><\/p>\n<p><span lang=\"EN-GB\">After pressing the button a few times and seeing the memory increasing, attach using <strong>cdb,<\/strong> load up Son of Strike (SOS) and do <strong>&#8220;!DumpHeap \u2013stat<\/strong>&#8220;. We see that, at the bottom, the type that is using most memory is <strong>System.String<\/strong>. Because I pushed the button a few times and because there are other uses of <strong>System.String<\/strong>, there are 311714 objects: Some might well be valid and some are our leaked objects:<\/span><\/p>\n<p class=\"illustration\"><span lang=\"EN-GB\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/980-DumpHeap3.png\" alt=\"image\" border=\"0\" \/><\/span><\/p>\n<p><span lang=\"EN-GB\">We could go through each object and dump them out individually to see what they contain, but there are so many, to go through all of them would be a &#8220;right royal pain&#8221;. Instead we can use some of the debugger\u2019s inbuilt commands to process each object.<\/span><\/p>\n<p><span lang=\"EN-GB\">If we take a look at one of the strings by doing &#8220;<strong>!do address<\/strong>&#8220;, we can see that at offset <span class=\"mono\">0xC<\/span> there is a value called <strong>m_firstChar<\/strong>. If we do &#8220;<strong>du address+c<\/strong>&#8221; instead of using <strong>!do<\/strong> to dump the object, it will take the unicode string at <span class=\"mono\">0xC<\/span> bytes after the start of the object and display it:<\/span><\/p>\n<p class=\"illustration\"><span lang=\"EN-GB\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/980-ManualDump1.png\" alt=\"image\" border=\"0\" \/><\/span><\/p>\n<p><span lang=\"EN-GB\">Now that we know that the actual string is 12 <span class=\"mono\">(0xC)<\/span> bytes from the location we get from <strong>!DumpHeap,<\/strong> we can use the debugger\u2019s own <strong>foreach<\/strong> iterator to do something interesting with the string. So if you run the following command:<\/span><\/p>\n<pre><span lang=\"EN-GB\"><strong>.foreach (location {!DumpHeap -type System.String -short} ) {du ${location}+c;}<\/strong><\/span><\/pre>\n<p><span lang=\"EN-GB\">This runs the command &#8220;<strong>!DumpHeap -type System.String \u2013short<\/strong>&#8221; and for each value that is returned, runs &#8220;<strong>du location+c<\/strong>&#8221; which outputs the string without the extra clr object <strong>gumpf<\/strong>, so if you run this you will see the address of the string followed by the actual unicode string. The strings show a load of values that are normal in a process, and then a whole load of strings such as &#8220;Hello There, I am numberr x&#8221;:<\/span><\/p>\n<p class=\"illustration\"><span lang=\"EN-GB\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/980-foreach1.png\" alt=\"image\" border=\"0\" \/><\/span><\/p>\n<p><span lang=\"EN-GB\">If you look at the total output most of the strings are the same so it shows that the object using up most of our memory is a string, but a slightly different one each time. In this specific case I would search the source for &#8220;Hello There, I am&#8221; and see where it is built and that should help us track down what the cause of the leak is. As an alternative, let\u2019s take the <strong>foreach<\/strong> operator and apply the <strong>GCRoot<\/strong> command to it.<\/span><\/p>\n<p><span lang=\"EN-GB\">The <strong>GCRoot<\/strong> is a slow command: If we run it against all the strings in the process, including the ones we are not interested in, it would take an unreasonable amount of time to complete; so again we can use the debugger\u2019s in built commands to help. There are two ways to combine commands to make something more useful, the first is the way we saw above and that is to type everything onto one line, which is fine for a simple bit of automation but we will need to do something a litte more complex, what we are going to do here is:<\/span><\/p>\n<ol>\n<li><span lang=\"EN-GB\">Get a list of all the System.String objects<\/span><\/li>\n<li><span lang=\"EN-GB\"><span lang=\"EN-GB\">For Each String:<\/span><\/span>\n<ol>\n<li>If it matches the wildcard &#8220;*Hello*&#8221; run !GCRoot against it<\/li>\n<li>If it doesn\u2019t match then ignore it<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p><span lang=\"EN-GB\">If we use a single line for this then it would become difficult to read and also difficult to write so instead we can use a debugger script, if you copy this into a text document and save it somewhere on your machine with your debugger tools:<\/span><\/p>\n<pre>.foreach (location {!DumpHeap -type System.String -short} ){                                    \r\n    .block{ as \/mu ${\/v:string} ${location}+c\r\n          .block{ .catch{\r\n               .if( $spat( \" ${string} \", \"*Hello*\")){.echo ${string}; !GCRoot -nostacks ${location};}\r\n               }  \r\n          }\r\n          ad ${\/v:string};                                                 \r\n     }                                             \r\n }<\/pre>\n<p><span lang=\"EN-GB\">(The script is also attached to the article in the zip file. It is called <strong>ForEachStringDumpMatchingGCRoot.txt<\/strong>)<\/span><\/p>\n<p><span lang=\"EN-GB\">We can then run this from inside the debugger by doing:<\/span><\/p>\n<p><strong><span lang=\"EN-GB\">&#8220;$&gt;&lt;C:\\PathToScript\\ ForEachStringDumpMatchingGCRoot.txt&#8221;<\/span><\/strong><\/p>\n<p><span lang=\"EN-GB\">You should see something like this:<\/span><\/p>\n<p class=\"illustration\"><span lang=\"EN-GB\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/980-ScriptOutput1.png\" alt=\"image\" border=\"0\" \/><\/span><\/p>\n<p><span lang=\"EN-GB\">At the top we see a number of syntax errors, these are because there is no way to quote the strings we are checking and they happen to break the script by including a quote, we get around this by ignoring errors using the .catch block and we see the output from any which fail so we can check those manually if we wanted.<\/span><\/p>\n<p><span lang=\"EN-GB\">The script is fairly simple, it runs a <strong>foreach<\/strong> over the output from &#8220;<strong>DumpHeap \u2013type System.String<\/strong>&#8220;, then stores the Unicode string that is at the location+c in an alias called <strong>${string}.<\/strong> It then uses the .if command to check whether the string matches the pattern &#8220;*Hello*&#8221;. If you don\u2019t want to do a pattern match then you can use <strong>$scmp<\/strong> for case sensitive or <strong>$scmpi<\/strong> for case-insensitive comparisons.<\/span><\/p>\n<p><span lang=\"EN-GB\">If a match is found, then it dumps the string and then calls <strong>GCRoot<\/strong>. The csharp code that created the objects looks like:<\/span><\/p>\n<pre>GCHandle.Alloc(stringNumeroUno, GCHandleType.Pinned);<\/pre>\n<p><span lang=\"EN-GB\">Because the handle isn\u2019t saved, there is a reference to the handle but the handle isn\u2019t rooted anywhere so the output of GCRoot is fairly useless:<\/span><\/p>\n<pre><span lang=\"EN-GB\" style=\"color: black;\">DOMAIN(00000000005B9860):HANDLE(Pinned):7417c8:Root: 000000000656a088(System.String)<\/span><\/pre>\n<p><span lang=\"EN-GB\">All this tells us that in the domain <span class=\"mono\">00000000005B9860<\/span> there is a pinned handle to our string (<span class=\"mono\">000000000656a088<\/span>). Normally at this point we would be a little stuck, if the object was created using the new operator we could set a breakpoint on the constructor and wait for the objects to be created: However, if we take a look at the MSIL for this particular problem we can see why this wouldn\u2019t work here:<\/span><\/p>\n<pre>.method public hidebysig newslot virtual final\r\n        instance void  Perform() cil managed\r\n{\r\n  \/\/ Code size       61 (0x3d)\r\n  .maxstack  2\r\n  .locals init ([0] int32 i,\r\n           [1] string stringNumeroUno,\r\n           [2] bool CS$4$0000)\r\n  IL_0000:  nop\r\n  IL_0001:  ldc.i4.0\r\n  IL_0002:  stloc.0\r\n  IL_0003:  br.s       IL_0025\r\n  IL_0005:  nop\r\n  IL_0006:  ldstr      \"Hello There, I am numberr \"\r\n  IL_000b:  ldloca.s   i\r\n  IL_000d:  call       instance string [mscorlib]System.Int32::ToString()\r\n  IL_0012:  call       string [mscorlib]System.String::Concat(string,\r\n                                                              string)g)\r\n  IL_0017:  stloc.1\r\n  IL_0018:  ldloc.1\r\n  IL_0019:  ldc.i4.3\r\n  IL_001a:  call       valuetype [mscorlib]System.Runtime.InteropServices.GCHandle\r\n      [mscorlib]System.Runtime.InteropServices.GCHandle::Alloc(object,\r\n      valuetype [mscorlib]System.Runtime.InteropServices.GCHandleType)\r\n  IL_001f:  pop\r\n  IL_0020:  nop\r\n  IL_0021:  ldloc.0\r\n  IL_0022:  ldc.i4.1\r\n  IL_0023:  add\r\n  IL_0024:  stloc.0\r\n  IL_0025:  ldloc.0\r\n  IL_0026:  ldc.i4     0x186a0\r\n  IL_002b:  clt\r\n  IL_002d:  stloc.2\r\n  IL_002e:  ldloc.2\r\n  IL_002f:  brtrue.s   IL_0005\r\n  IL_0031:  ldstr      \"Complete\"\r\n  IL_0036:  call       valuetype [System.Windows.Forms]\r\n      System.Windows.Forms.DialogResult [System.Windows.Forms]\r\n      System.Windows.Forms.MessageBox::Show(string)\r\n  IL_003b:  pop\r\n  IL_003c:  ret\r\n} \/\/ end of method GCAllocd::Perform<\/pre>\n<p><span lang=\"EN-GB\">Line IL_006 shows that <strong>ldstr<\/strong> is used instead of <strong>newobj<\/strong> <strong>nope<\/strong> and then having the constructor called. So to track down where the location that the strings are being created we must take what we know:<\/span><\/p>\n<ul>\n<li><span lang=\"EN-GB\">There are a whole load of strings starting &#8220;Hello There,\u2026&#8221;<\/span><\/li>\n<li><span lang=\"EN-GB\">Each string has a number after it<span style=\"font-family: Times New Roman; font-size: 7pt;\">#<\/span><\/span><\/li>\n<li><span lang=\"EN-GB\">The references are rooted and pinned.<\/span><\/li>\n<\/ul>\n<p><span lang=\"EN-GB\">We can be certain that <strong>GCHandle.Alloc<\/strong> is being called somewhere, otherwise we would have an actual reference to the object. We also know that, because the string is modified from a standard string to include a number, that <strong>String.Concat<\/strong> is most likely being called: it will still call <strong>String.Concat<\/strong> even if a string is concatenated using &#8220;+&#8221;. Although we can assume that a number is converted to a string, this could be done through <strong>Int32.ToString<\/strong>, <strong>Int64.ToString<\/strong> or any of the number types, so you might potentially have to set quite a few breakpoints.<\/span><\/p>\n<p><span lang=\"EN-GB\">From our three options, we will try setting a breakpoint on <strong>String.Concat<\/strong>. To set the breakpoint we need to find the String object\u2019s method table so we can get the method description which will give use the address of Concat to set the breakpoint so:<\/span><\/p>\n<p><strong><span lang=\"EN-GB\">!Name2EE * System.String<\/span><\/strong><\/p>\n<p style=\"margin-left: 0.5in;\"><span lang=\"EN-GB\">This should show the Name <strong>System.String<\/strong> and the <strong>MethodTable<\/strong>, on my machine it is &#8220;000007fef52d34b8&#8221;<\/span><\/p>\n<p><strong><span lang=\"EN-GB\">!DumpMT \u2013md 000007fef52d34b8<\/span><\/strong><\/p>\n<p style=\"margin-left: 0.5in;\"><span lang=\"EN-GB\">This should list all the methods, find concat and from the <strong>MethodDescription<\/strong> take the value, on my system it is &#8220;000007fef4de9250&#8221;<\/span><\/p>\n<p><strong><span lang=\"EN-GB\">!bpmd -md 000007fef4de9250<\/span><\/strong><\/p>\n<p style=\"margin-left: 0.5in;\"><span lang=\"EN-GB\">Now what this does is to set a breakpoint on each of the different flavours of <strong>Concat<\/strong>, if you use .NET Reflector against <strong>System.String<\/strong> you will see 11 different <strong>Concat<\/strong>s, we get a breakpoint for each.<\/span><\/p>\n<p><span lang=\"EN-GB\">If you ..<\/span><\/p>\n<ul>\n<li><span lang=\"EN-GB\">do &#8220;<strong>g<\/strong>&#8220;, this will restart the application and when you press &#8220;GC Alloc&#8221; it should hit a breakpoint in the debugger<\/span><\/li>\n<li><span lang=\"EN-GB\">do &#8220;<strong>!CLRStack<\/strong>&#8221; and you will see the stack trace that caused the string to be pinned.<\/span><\/li>\n<\/ul>\n<p><span lang=\"EN-GB\">Normally you won\u2019t have a handy button that you can press in order to see what the cause is, so you might have to wait a little while until it breaks into the debugger.<\/span><\/p>\n<p><span lang=\"EN-GB\">Once you know from where the objects are being created, you can see why they are being allocated and where they are being pinned. The reason why they are pinned depends on the original programmer, but at least you can see where your memory is going and can take action to free it as appropriate.<\/span><\/p>\n<p><span lang=\"EN-GB\">There is a debate as to whether our next example really is a memory leak, I think that it doesn\u2019t really matter what you call it: If an object subscribes to an event and that stops the garbage collector from freeing the memory when it is finished with it, then your process will not run efficiently and could run out of memory whether or not it is a genuine leak.<\/span><\/p>\n<p><span lang=\"EN-GB\">In this example, a static class has an event that objects subscribe to. These objects go out of scope so the memory they use should be freed. However, because the static class has a reference to each object via an <strong>EventHandler,<\/strong> the objects hang around.<\/span><\/p>\n<p><span lang=\"EN-GB\">If you run the sample app and<\/span><\/p>\n<ul>\n<li><span lang=\"EN-GB\">press the &#8220;Delegate Leak&#8221; button a few times<\/span><\/li>\n<li><span lang=\"EN-GB\">break into it with the debugger<\/span><\/li>\n<li><span lang=\"EN-GB\">run &#8220;!DumpHeap \u2013stat&#8221;<\/span><\/li>\n<\/ul>\n<p><span lang=\"EN-GB\">.. then at the bottom we see something like:<\/span><\/p>\n<p class=\"illustration\"><span lang=\"EN-GB\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/980-DumpHeap4.png\" alt=\"image\" border=\"0\" \/><\/span><\/p>\n<p><span lang=\"EN-GB\">Here we see a large number (in this particular case 12000+) of a number of different types including &#8220;<strong>leak.UcLeaker<\/strong>&#8221; . If we then dump out those objects by getting the <strong>MethodTable<\/strong> from the first column and doing &#8220;!<strong>DumpHeap \u2013mt [MethodTable<\/strong>]&#8221;, and do &#8220;!<strong>GCRoot -nostacks<\/strong>&#8221; on a few at random , we can see that there is an object &#8220;<strong>leak.DelegateLeak<\/strong>&#8221; which has a reference to a &#8220;<strong>System.EventHandler<\/strong>&#8221; which has a reference to an array of <strong>System.Objects<\/strong> which reference an <strong>EventHandler<\/strong> which reference our object we originally did <strong>GCRoot<\/strong> against:<\/span><\/p>\n<p class=\"illustration\"><span lang=\"EN-GB\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/980-GCRoot2.png\" alt=\"image\" border=\"0\" \/><\/span><\/p>\n<p><span lang=\"EN-GB\">We can then take a look at the <strong>System.Object[]<\/strong> because it is useful to know if it is one object that has many references or one object per reference (because if it is just one object then it is likely a static instance so should help to track down the problem faster), if you do &#8220;<strong>!do<\/strong>&#8221; against the address of the object array.<\/span><\/p>\n<p><span lang=\"EN-GB\">We see that there are quite a few elements, running &#8220;<strong>!da<\/strong>&#8221; against the address dumps each element and if you let it run, it will list the objects that are leaking, but at some point the addresses will change to &#8220;null&#8221;: This is because the array has been resized with appropriate space for more objects to be added. In this case, the element number where it changes to null should be approximately the same as the amount of leaked objects we had in our output from &#8220;!<strong>DumpHeap \u2013stat<\/strong>&#8220;.<\/span><\/p>\n<p class=\"illustration\">\u00a0<\/p>\n<p class=\"illustration\"><span lang=\"EN-GB\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/980-DumpHeap5.png\" alt=\"image\" border=\"0\" \/><\/span><\/p>\n<p><span lang=\"EN-GB\">So we now know that one class has a reference to all our objects: Freeing that object will free our references, but how do we know what the reference is for other than it is for an event? As always in debugging, there are a few different approaches we can take to this, we can \u2026<\/span><\/p>\n<ul>\n<li><span lang=\"EN-GB\"><span lang=\"EN-GB\">examine the <strong>EventHandler<\/strong> objects which have a <strong>MethodPtr<\/strong> to see what method on the leaked class is being called,<\/span><\/span><\/li>\n<li><span lang=\"EN-GB\">we can set a breakpoint on that <strong>MethodPtr<\/strong> to see when (if ever) it gets called<\/span><\/li>\n<li><span lang=\"EN-GB\">we could set a break point on the <strong>EventHandler<\/strong> constructor and wait to see where it is actually set.<\/span><\/li>\n<\/ul>\n<p><span lang=\"EN-GB\">Each way has its own merits. Here we will see how to find out where the event goes to. To do this, dump out all of the <strong>EventHandlers<\/strong> in the program: If there are too many extra handlers that aren\u2019t involved in your problem, then choose the ones that you want from the output from the <strong>!da<\/strong> on the <strong>System.Object[]<\/strong> we did earlier.<\/span><\/p>\n<div class=\"listing\">\n<p><strong><span lang=\"EN-GB\">.foreach (location {!DumpHeap -type System.EventHandler -short} ) {!do location;}<\/span><\/strong><\/p>\n<\/div>\n<p><span lang=\"EN-GB\">If you scan the output, you see the <strong>_target<\/strong>. This is the actual object that will receive the event and you can run &#8220;<strong>!do<\/strong>&#8221; against that if you wanted to see what it was, but as we know it is our &#8220;<strong>leak.UcLeaker<\/strong>&#8221; class we won\u2019t bother. The second thing you should see is the <strong>_methodPtr<\/strong> which should be the same on all the <strong>EventHandler<\/strong> objects:<\/span><\/p>\n<p class=\"illustration\"><span lang=\"EN-GB\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/980-DoEventHandlers.png\" alt=\"image\" border=\"0\" \/><\/span><\/p>\n<p><span lang=\"EN-GB\">The <strong>_methodPtr<\/strong> is a <strong>IntPtr<\/strong> to the memory address that will be run when the event fires, you can run &#8220;<strong>!ip2md<\/strong>&#8221; against the <strong>_methodPtr<\/strong> but this normally fails to resolve the method. If it does fail then the easiest thing to do is to set a breakpoint on that address, run the program, and wait for it to break (Press the &#8220;Fire Events&#8221; button). When it breaks, if you do a &#8220;<strong>!CLRStack<\/strong>&#8221; you will likely find yourself in a mysterious method called &#8220;<strong>System.EventHandler.Invoke<\/strong>&#8220;. This does some magic to call your event, it will setup some variables and then jump into your method, so step through the code pressing &#8220;p&#8221; and you can either be brave and wait until you get a <strong>jmp<\/strong> or you can keep doing a &#8220;<strong>!CLRStack<\/strong>&#8221; until you see the method you were looking for, &#8220;<strong>leak.UcLeaker.EventDelegate<\/strong>&#8220;:<\/span><\/p>\n<p class=\"illustration\"><span lang=\"EN-GB\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/980-FindEventHandlers2.png\" alt=\"image\" border=\"0\" \/><\/span><\/p>\n<p><span lang=\"EN-GB\">Once you know that you have an event and the method it points at, it should be fairly simple to search your code and find where the <span class=\"mono\">+=<\/span> is being called to then add a <span class=\"mono\">-=<\/span> at the appropriate place.<\/span><\/p>\n<p><span lang=\"EN-GB\">If you wanted to approach this from the other point of view and see where the <strong>EventHandler<\/strong> objects are being created to find the breakpoint location, you can use <strong>!Name2EE<\/strong> to get the method table, then you use <strong>!DumpMT<\/strong> with the <strong>\u2013md<\/strong> parameter to get a the method description for the constructor on the <strong>EventHandler<\/strong> which you pass to <strong>!bpmd.<\/strong><\/span><\/p>\n<h2><span lang=\"EN-GB\">Summary<\/span><\/h2>\n<p><span lang=\"EN-GB\">It is fairly simple to understand how to find out what it is that is using your memory with <strong>Son of Strike (SOS.DLL)<\/strong> by using <strong>DumpHeap<\/strong> and how to find out why the objects are alive using <strong>GCRoot<\/strong>. If you couple these two with the advanced debugging commands such as <strong>.foreach,<\/strong> it really does become quite simple to quickly identify bugs which can lead to memory leaks or just poor performance using the debugging tools for windows and SOS. Despite their rather Spartan user-interface, they are free and, after some work in learning how to use them, can be a joy to use.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Investigating a subtle memory leak can be tricky business, but things are made easier by using The .NET framework&#8217;s  tool SOS (Son of Strike) which is a debugger extension for debugging managed code, used  in collaboration with the Windows debugger.&hellip;<\/p>\n","protected":false},"author":59464,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143538],"tags":[4143,4229],"coauthors":[11314],"class_list":["post-839","post","type-post","status-publish","format-standard","hentry","category-dotnet-development","tag-net","tag-net-framework"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/839","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\/59464"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=839"}],"version-history":[{"count":14,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/839\/revisions"}],"predecessor-version":[{"id":74488,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/839\/revisions\/74488"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=839"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=839"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=839"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=839"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}