Deep Dumpster DivingA close look at .Net garbage collection<br />Ronn Black<br />October 2009<br />
Why should I care?<br />
Demo 1 (Word Count)<br />using System;<br />usingSystem.Collections.Generic;<br />usingSystem.Diagnostics;<br />using Syst...
using System;<br />usingSystem.Collections.Generic;<br />usingSystem.Threading;<br />usingSystem.Runtime.CompilerServices;...
Unmanaged Memory Management <br />
Hi Address<br />Unused Area<br />Unused Area<br />Args & Variables<br />Stack<br />Stack Pointer<br />Heap<br />Reserved<b...
NextObjPtr<br />
NextObjPtr<br />
Roots<br />NextObjPtr<br />
NextObjPtr<br />Roots<br />
Finalizers<br />=<br />~MyClass(){	//Do work here…}<br />MyClass.Finalize(){	//Do work here…}<br />
Roots<br />Finalization Queue<br />I<br />I<br />H<br />F<br />G<br />E<br />F<br />C<br />E<br />Freachable Queue<br />D<...
Roots<br />Finalization Queue<br />I (x)<br />I (x)<br />H (x)<br />F<br />G (x)<br />E (x)<br />F<br />C<br />E (x)<br />...
Roots<br />Finalization Queue<br />F<br />I (x)<br />C<br />F<br />Freachable Queue<br />E (x)<br />D<br />C<br />I (x)<br...
Optimizations<br />Generations<br />Newly created objects tend to have short lives.<br />The older an object is, the longe...
using System;<br />usingSystem.Collections.Generic;<br />usingSystem.Threading;<br />usingSystem.Runtime.CompilerServices;...
Demo 4 (CLR Profile Word Count)<br />using System;<br />usingSystem.Collections.Generic;<br />usingSystem.Diagnostics;<br ...
IDisposable<br />public class MyClass : IDisposable<br />{<br />public void Dispose()<br />	{<br />		Dispose(true);<br />G...
Using<br />using System;<br />using System.Collections.Generic;<br />using System.Diagnostics;<br />
Using<br />using System;<br />using System.Collections.Generic;<br />using System.Diagnostics;<br />using (MyClass c = new...
Demo 5 - optimize<br />using System;<br />using System.Collections.Generic;<br />using System.Diagnostics;<br />using Syst...
TotalRelocatedFinal	Gen 0 	Gen 1	Large Object Heap6,578,038	96,608	5,057,272	1,400,580	12	3,535,4645,473,972	101,501	1,441...
Types of Memory Leaks<br />Managed leaks – persistent object holds a reference to an object expected to be garbage collect...
Demo 7 - Leaky program?<br />
 public partial class ChildForm : Form<br />    {<br />        public ChildForm()<br />        {<br />InitializeComponent(...
 public partial class ChildForm : Form<br />    {<br />        public ChildForm()<br />        {<br />InitializeComponent(...
Contact & Reference Material<br />Ronn Black  rblack@btsoft.org<br />http://msdn.microsoft.com/en-us/library/ms973837.aspx...
Upcoming SlideShare
Loading in …5
×

Deep Dumpster Diving

1,066 views
967 views

Published on

Slides from Session "Deep Dumpster Diving"

Published in: Sports, Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,066
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
6
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • IntroductionThis is my first time doing this and I’m sure I’ll muck things up somewhere along the way. I don’t consider myself an expert on this subject. I simply have done enough investigation in this area to have some interesting insights on the subject.
  • Why should I care?After all one of the reasons you chose a managed environment is to forget about memory management. You pay a price for garbage collection. Bad algorithms cause the garbage collector to work harder. Simple program, Count the number of words in a document using string.Split() and then get the length of the array.
  • This program is spending about 20 to 50% of its time just trying to manage the memory. Paying attention to memory can give even a small program a 20 to 50% performance boost. More efficient alternatives later for now just understand it creates a lot of objects and throws them away. In this run there were 2 peaks that reached a little over 70%.
  • The stack is where local variables are allocated.The heap is where malloc and new allocate space.
  • As programs request memory the system allocates it from the heap.
  • As programs release memory open spots appear in the heap. Eventually this area becomes fragmented and the system has to search through a list of free space to find enough space for the memory requested. The more fragmented memory becomes the longer this can take.
  • .Net reserves a contiguous region of memory that it will use for the managed heap.Frameworkalso maintains a pointer to the location where the next object will be allocated.
  • Application creates some objects. If it will fit the location the NewObjPtr points to is used for the new object, the constructor of the new object is called and the address of the object is returned to the calling program.NewObjPtr is advanced beyond the new object and points to where the next object will be created in the heap.
  • Deep Dumpster Diving

    1. 1. Deep Dumpster DivingA close look at .Net garbage collection<br />Ronn Black<br />October 2009<br />
    2. 2. Why should I care?<br />
    3. 3. Demo 1 (Word Count)<br />using System;<br />usingSystem.Collections.Generic;<br />usingSystem.Diagnostics;<br />using System.IO;<br />publicclassMyClass<br />{<br /> publicstaticvoidRunSnippet()<br /> {<br /> while(true)<br /> {<br /> Stopwatch watch = new Stopwatch();<br />watch.Start();<br />StreamReadersr = newStreamReader(@&quot;C:UsersRonnDocumentsMy Code SnippetsGarbage Collectioncatcher.txt&quot;);<br /> string text = sr.ReadToEnd();<br />intwordCount = text.Split().Length;<br />Console.WriteLine(&quot;{0} Words&quot;, wordCount);<br />watch.Stop();<br />Console.WriteLine(watch.ElapsedMilliseconds + &quot; Milliseconds&quot;);<br /> }<br /> }<br />
    4. 4.
    5. 5. using System;<br />usingSystem.Collections.Generic;<br />usingSystem.Threading;<br />usingSystem.Runtime.CompilerServices;<br />publicclassMyClass<br />{<br /> static Byte[] bytes;<br /> publicstaticvoidRunSnippet()<br /> {<br /> Timer tmr = new Timer(M, null, 0, 1000);<br />Thread.Sleep(20);<br /> for(int i = 0; i &lt; 1000; i++)<br /> bytes = new Byte[2000];<br />Console.ReadLine();<br /> }<br /> staticvoid M(object state)<br /> {<br />Console.WriteLine(&quot;M - &quot; + DateTime.Now);<br /> }<br />Demo 2<br />
    6. 6. Unmanaged Memory Management <br />
    7. 7. Hi Address<br />Unused Area<br />Unused Area<br />Args & Variables<br />Stack<br />Stack Pointer<br />Heap<br />Reserved<br />Low Address<br />
    8. 8.
    9. 9.
    10. 10.
    11. 11.
    12. 12. NextObjPtr<br />
    13. 13. NextObjPtr<br />
    14. 14. Roots<br />NextObjPtr<br />
    15. 15. NextObjPtr<br />Roots<br />
    16. 16. Finalizers<br />=<br />~MyClass(){ //Do work here…}<br />MyClass.Finalize(){ //Do work here…}<br />
    17. 17. Roots<br />Finalization Queue<br />I<br />I<br />H<br />F<br />G<br />E<br />F<br />C<br />E<br />Freachable Queue<br />D<br />C<br />B<br />A<br />
    18. 18. Roots<br />Finalization Queue<br />I (x)<br />I (x)<br />H (x)<br />F<br />G (x)<br />E (x)<br />F<br />C<br />E (x)<br />Freachable Queue<br />D<br />C<br />B (x)<br />A<br />
    19. 19. Roots<br />Finalization Queue<br />F<br />I (x)<br />C<br />F<br />Freachable Queue<br />E (x)<br />D<br />C<br />I (x)<br />A<br />E (x)<br />
    20. 20. Optimizations<br />Generations<br />Newly created objects tend to have short lives.<br />The older an object is, the longer it will survive. <br />Groups objects by age and collects younger objects more frequently than older objects.<br />All objects added to heap are in generation 0.<br />When an object survives the first garbage collection it is promoted to generation 1.<br />When garbage collection is triggered survivors from generation 1 are promoted to generation 2 and generation 0 survivors are promoted to gen 1.<br />As objects &quot;mature&quot;, they are moved to the next older generation until they reach gen 2. <br />
    21. 21. using System;<br />usingSystem.Collections.Generic;<br />usingSystem.Threading;<br />usingSystem.Runtime.CompilerServices;<br />publicclassMyClass<br />{<br /> static Byte[] bytes;<br /> publicstaticvoidRunSnippet()<br /> {<br /> Timer tmr = new Timer(M, null, 0, 1000);<br />Thread.Sleep(20);<br /> for(int i = 0; i &lt; 1000; i++)<br /> bytes = new Byte[2000];<br />Console.ReadLine();<br /> }<br /> staticvoid M(object state)<br /> {<br />Console.WriteLine(&quot;M - &quot; + DateTime.Now);<br /> }<br />Demo 3 – WTF??<br />
    22. 22. Demo 4 (CLR Profile Word Count)<br />using System;<br />usingSystem.Collections.Generic;<br />usingSystem.Diagnostics;<br />using System.IO;<br />publicclassMyClass<br />{<br /> publicstaticvoidRunSnippet()<br /> {<br /> while(true)<br /> {<br /> Stopwatch watch = new Stopwatch();<br />watch.Start();<br />StreamReadersr = newStreamReader(@&quot;C:UsersRonnDocumentsMy Code SnippetsGarbage Collectioncatcher.txt&quot;);<br /> string text = sr.ReadToEnd();<br />intwordCount = text.Split().Length;<br />Console.WriteLine(&quot;{0} Words&quot;, wordCount);<br />watch.Stop();<br />Console.WriteLine(watch.ElapsedMilliseconds + &quot; Milliseconds&quot;);<br /> }<br /> }<br />
    23. 23.
    24. 24.
    25. 25.
    26. 26.
    27. 27.
    28. 28.
    29. 29. IDisposable<br />public class MyClass : IDisposable<br />{<br />public void Dispose()<br /> {<br /> Dispose(true);<br />GC.SuppressFinalize(this);<br /> }<br />protected virtual void Dispose(bool disposing)<br /> {<br />if (!disposed)<br /> {<br />if (disposing)<br /> {<br />// Dispose managed resources. Ex: Components.Dispose();<br /> }<br />// Release ONLY unmanaged resources. Ex: CloseHandle(handle);<br /> }<br /> disposed = true;<br /> }<br />protected volatile bool disposed = false;<br /> ~MyClass() <br /> {<br /> Dispose(false);<br /> }<br />}<br />[ComVisible(true)]<br />public interface IDisposable<br />{<br /> void Dispose();<br />}<br />
    30. 30. Using<br />using System;<br />using System.Collections.Generic;<br />using System.Diagnostics;<br />
    31. 31. Using<br />using System;<br />using System.Collections.Generic;<br />using System.Diagnostics;<br />using (MyClass c = new MyClass())<br />{<br />//Do Some Work<br />}<br />
    32. 32. Demo 5 - optimize<br />using System;<br />using System.Collections.Generic;<br />using System.Diagnostics;<br />using System.IO;<br />public class MyClass<br />{<br /> public static void RunSnippet()<br /> {<br /> while(true)<br /> {<br /> Stopwatch watch = new Stopwatch();<br />watch.Start();<br /> using(StreamReadersr = new StreamReader(@&quot;C:…Garbage Collectioncatcher.txt&quot;))<br /> {<br /> string line = &quot;&quot;;<br />intwordCount = 0;<br /> while((line = sr.ReadLine()) != null)<br /> {<br />wordCount += line.Split().Length;<br /> }<br />Console.WriteLine(&quot;{0} Words&quot;, wordCount);<br /> }<br />watch.Stop();<br />Console.WriteLine(watch.ElapsedMilliseconds + &quot; Milliseconds&quot;);<br /> }<br /> }<br />
    33. 33.
    34. 34. TotalRelocatedFinal Gen 0 Gen 1 Large Object Heap6,578,038 96,608 5,057,272 1,400,580 12 3,535,4645,473,972 101,501 1,441,201 2,097,172 103,992 9,328======== ======== ======== ========= ======== =========== -1,104,066 +4,893 -3,617,071 +696,592 +103,980 -3,526,136<br />
    35. 35. Types of Memory Leaks<br />Managed leaks – persistent object holds a reference to an object expected to be garbage collected.<br />Unmanaged leaks - using unmanaged resources, dll’s or COM objects that leak memory.<br />
    36. 36.
    37. 37.
    38. 38.
    39. 39. Demo 7 - Leaky program?<br />
    40. 40.
    41. 41.
    42. 42.
    43. 43.
    44. 44.
    45. 45. public partial class ChildForm : Form<br /> {<br /> public ChildForm()<br /> {<br />InitializeComponent();<br /> }<br /> private void ChildForm_Load(object sender, EventArgs e)<br /> {<br />Program.Skin.PropertyChanged += new PropertyChangedEventHandler(Skin_PropertyChanged);<br /> }<br /> void Skin_PropertyChanged(object sender, PropertyChangedEventArgs e)<br /> {<br />this.BackColor = Program.Skin.BackgroundColor;<br /> this.label1.ForeColor = Program.Skin.ForegroundColor;<br /> }<br /> }<br />
    46. 46. public partial class ChildForm : Form<br /> {<br /> public ChildForm()<br /> {<br />InitializeComponent();<br /> }<br /> private void ChildForm_Load(object sender, EventArgs e)<br /> {<br />Program.Skin.PropertyChanged += new PropertyChangedEventHandler(Skin_PropertyChanged);<br /> }<br /> void Skin_PropertyChanged(object sender, PropertyChangedEventArgs e)<br /> {<br />this.BackColor = Program.Skin.BackgroundColor;<br /> this.label1.ForeColor = Program.Skin.ForegroundColor;<br /> }<br /> protected override void OnClosing(CancelEventArgs e)<br /> {<br />base.OnClosing(e);<br />Program.Skin.PropertyChanged -= Skin_PropertyChanged;<br /> }<br /> }<br />
    47. 47. Contact & Reference Material<br />Ronn Black rblack@btsoft.org<br />http://msdn.microsoft.com/en-us/library/ms973837.aspx (Garbage Collector Basics and Performance Hints)<br />http://www.microsoft.com/downloads/details.aspx?FamilyID=a362781c-3870-43be-8926-862b40aa0cd0&DisplayLang=en<br />CLR Profiler for .Net 2.0<br />http://www.openasthra.com/multithreading/heap-overview/ Heap Overview<br />http://74.125.155.132/search?q=cache:44hDjSztDf4J:doc.bughunter.net/buffer-overflow/advanced-malloc-exploits.html+malloc+overview&cd=21&hl=en&ct=clnk&gl=us Advanced Malloc exploits<br />http://msdn.microsoft.com/en-us/magazine/cc534993.aspx<br />http://www.microsoft.com/downloads/details.aspx?FamilyId=A362781C-3870-43BE-8926-862B40AA0CD0&displaylang=en CLR Profiler<br />

    ×