45
DEEP DUMPSTER DIVING A close look at .Net garbage collect Ronn Black October 2010

Deep dumpster diving 2010

Embed Size (px)

Citation preview

Page 1: Deep dumpster diving 2010

DEEP DUMPSTER DIVING

A close look at .Net garbage collection

Ronn Black

October 2010

Page 2: Deep dumpster diving 2010

Why should I care?

Page 3: Deep dumpster diving 2010

Demo 1 (Word Count)using System;using System.Collections.Generic;using System.Diagnostics;using System.IO;

public class MyClass{

public static void RunSnippet(){

while(true){

Stopwatch watch = new Stopwatch();watch.Start();StreamReader sr = new StreamReader(@"C:\Users\Ronn\Documents\My

Code Snippets\Garbage Collection\catcher.txt");string text = sr.ReadToEnd();int wordCount = text.Split().Length;Console.WriteLine("{0} Words", wordCount);watch.Stop();Console.WriteLine(watch.ElapsedMilliseconds + " Milliseconds");

}

}

Page 4: Deep dumpster diving 2010
Page 5: Deep dumpster diving 2010

using System;using System.Collections.Generic;using System.Threading;using System.Runtime.CompilerServices;

public class MyClass{

static Byte[] bytes;public static void RunSnippet(){

Timer tmr = new Timer(M, null, 0, 1000);Thread.Sleep(20);for(int i = 0; i < 1000; i++)

bytes = new Byte[2000];

Console.ReadLine();}

static void M(object state){

Console.WriteLine("M - " + DateTime.Now);}

Demo 2

Page 6: Deep dumpster diving 2010

Unmanaged Memory Management

Page 7: Deep dumpster diving 2010

Unused AreaHi Address

Low Address

ReservedReserved

Args & VariablesArgs & Variables

StackStack

HeapHeap

Stack PointerUnused Area

Page 8: Deep dumpster diving 2010
Page 9: Deep dumpster diving 2010
Page 10: Deep dumpster diving 2010
Page 11: Deep dumpster diving 2010
Page 12: Deep dumpster diving 2010

NextObjPtr

Page 13: Deep dumpster diving 2010

NextObjPtr

Page 14: Deep dumpster diving 2010

RootsRoots

NextObjPtr

Page 15: Deep dumpster diving 2010

RootsRoots

NextObjPtr

Page 16: Deep dumpster diving 2010

~MyClass(){

//Do work here…}

MyClass.Finalize(){

//Do work here…}

=

Finalizers

Page 17: Deep dumpster diving 2010

RootsRoots

F

G

A

B

C

E

H

I

DFreachable Queue

C

E

F

I

Finalization Queue

Page 18: Deep dumpster diving 2010

F

G (x)

A

RootsRoots

B (x)

C

E (x)

H (x)

I (x)

DFreachable Queue

C

E (x)

F

I (x)

Finalization Queue

Page 19: Deep dumpster diving 2010

F

A

RootsRoots

C

E (x)

I (x)

D

E (x)

I (x)

Freachable Queue

C

F

Finalization Queue

Page 20: Deep dumpster diving 2010

Optimizations Generations

Newly created objects tend to have short lives. The older an object is, the longer it will survive. Groups objects by age and collects younger objects more

frequently than older objects. All objects added to heap are in generation 0. When an object survives the first garbage collection it is promoted

to generation 1. When garbage collection is triggered survivors from generation 1

are promoted to generation 2 and generation 0 survivors are promoted to gen 1.

As objects "mature", they are moved to the next older generation until they reach gen 2.

Page 21: Deep dumpster diving 2010

using System;using System.Collections.Generic;using System.Threading;using System.Runtime.CompilerServices;

public class MyClass{

static Byte[] bytes;public static void RunSnippet(){

Byte[] bytes;Timer tmr = new Timer(M, null, 0, 1000);Thread.Sleep(20);for(int i = 0; i < 1000; i++)

bytes = new Byte[2000];

Console.ReadLine();}

static void M(object state){

Console.WriteLine("M - " + DateTime.Now);}

Demo 3 – WTF??

Page 22: Deep dumpster diving 2010

using System;using System.Collections.Generic;using System.Threading;using System.Runtime.CompilerServices;

public class MyClass{

static Byte[] bytes;public static void RunSnippet(){

Byte[] bytes;Timer tmr = new Timer(M, null, 0, 1000);Thread.Sleep(20);for(int i = 0; i < 1000; i++)

bytes = new Byte[2000];Console.WriteLine(bytes.Length);Console.ReadLine();

}

static void M(object state){

Console.WriteLine("M - " + DateTime.Now);}

Demo 3 – WTF??

Page 23: Deep dumpster diving 2010

using System;using System.Collections.Generic;using System.Threading;using System.Runtime.CompilerServices;

public class MyClass{

static Byte[] bytes;public static void RunSnippet(){

Byte[] bytes;Timer tmr = new Timer(M, null, 0, 1000);Thread.Sleep(20);for(int i = 0; i < 1000; i++)

{bytes = new Byte[2000];

Console.WriteLine(“XX”); }

Console.ReadLine();}

static void M(object state){

Console.WriteLine("M - " + DateTime.Now);}

Demo 3 – WTF??

Page 24: Deep dumpster diving 2010

Demo 4 (CLR Profile Word Count)

using System;using System.Collections.Generic;using System.Diagnostics;using System.IO;

public class MyClass{

public static void RunSnippet(){

while(true){

Stopwatch watch = new Stopwatch();watch.Start();StreamReader sr = new StreamReader(@"C:\Users\Ronn\Documents\My

Code Snippets\Garbage Collection\catcher.txt");string text = sr.ReadToEnd();int wordCount = text.Split().Length;Console.WriteLine("{0} Words", wordCount);watch.Stop();Console.WriteLine(watch.ElapsedMilliseconds + " Milliseconds");

}

}

Page 25: Deep dumpster diving 2010
Page 26: Deep dumpster diving 2010
Page 27: Deep dumpster diving 2010
Page 28: Deep dumpster diving 2010
Page 29: Deep dumpster diving 2010
Page 30: Deep dumpster diving 2010
Page 31: Deep dumpster diving 2010

IDisposable public class MyClass : IDisposable

{

public void Dispose()

{

Dispose(true);

GC.SuppressFinalize(this);

}

protected virtual void Dispose(bool disposing)

{

if (!disposed)

{

if (disposing)

{

// Dispose managed

resources. Ex: Components.Dispose();

}

// Release ONLY unmanaged

resources. Ex: CloseHandle(handle);

}

disposed = true;

}

protected volatile bool disposed = false;

~MyClass()

{

Dispose(false);

}

}

[ComVisible(true)]

public interface IDisposable

{

void Dispose();

}

Page 32: Deep dumpster diving 2010

Usingusing System;

using System.Collections.Generic;

using System.Diagnostics;

Page 33: Deep dumpster diving 2010

Usingusing System;

using System.Collections.Generic;

using System.Diagnostics;

using (MyClass c = new MyClass())

{

//Do Some Work

}

Page 34: Deep dumpster diving 2010

Demo 5 - optimizeusing System;using System.Collections.Generic;using System.Diagnostics;using System.IO;

public class MyClass{

public static void RunSnippet(){

while(true){

Stopwatch watch = new Stopwatch();watch.Start();using(StreamReader sr = new StreamReader(@"C:…Garbage Collection\

catcher.txt")){

string line = "";int wordCount = 0;while((line = sr.ReadLine()) != null){

wordCount += line.Split().Length;}Console.WriteLine("{0} Words", wordCount);

}watch.Stop();Console.WriteLine(watch.ElapsedMilliseconds + " Milliseconds");

}}

Page 35: Deep dumpster diving 2010
Page 36: Deep dumpster diving 2010

Total Relocated Final 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

Page 37: Deep dumpster diving 2010

Design patterns and Memory

Page 38: Deep dumpster diving 2010

Design patterns and MemoryCircular References.

Form

+ControlsControl

+Parent

Control

+Parent

Control

+Parent

Control

+Parent

Page 39: Deep dumpster diving 2010

Design patterns and Memory

public class Preferences

{

public Preferences instance;

public static Preferences GetPrefs()

{

if (instance == null)

instance = new

Preferences();

return instance;

}

public event PrefsChanged;

}

Page 40: Deep dumpster diving 2010

Design patterns and MemoryRooted objects (Singletons).

Form

+ControlsControl

+Parent

Control

+Parent

Control

+Parent

Control

+Parent

Preferences

$GetPrefs+PrefsChanged

Page 41: Deep dumpster diving 2010

Design patterns and MemoryLists, Hashtables, Dictionaries, etc.

List<T>

Control

+Parent

Control

+Parent

Control

+Parent

T

Page 42: Deep dumpster diving 2010

Design patterns and Memory

public class Foo

{

public static void DoSomething()

{

List<Bar> bars;

...

//Do Something

bar.Clear();

}

}

Page 43: Deep dumpster diving 2010

Design patterns and Memory

public class Foo

{

static Dictionary<string, Bar> _bars;

public static Foo()

{

//Initialize the

Lookup table

_bars = new

Dictionary<string, Bar>();

_bars.Add(“EndUp”,

new Bar());

...

}

}

Page 44: Deep dumpster diving 2010

Take Aways Don’t keep objects around unless you know you will

be using them again. Save these techniques for objects that are

expensive to create and are frequently used. Carefully consider use of type initializers and statics. Consider caching patterns so memory can be

reclaimed if needed. If you are using observable patterns be sure you

unsubscribe properly

Page 45: Deep dumpster diving 2010

Contact & Reference Material

http://msdn.microsoft.com/en-us/library/ms973837.aspx (Garbage Collector Basics and Performance Hints)

http://www.microsoft.com/downloads/details.aspx?FamilyID=a362781c-3870-43be-8926-862b40aa0cd0&DisplayLang=en (CLR Profiler for .Net 2.0)

http://www.openasthra.com/multithreading/heap-overview/ (Heap Overview) http://74.125.155.132/search?q=cache:44hDjSztDf4J:doc.bughunter.net/buff

er-overflow/advanced-malloc-exploits.html+malloc+overview&cd=21&hl=en&ct=clnk&gl=us Advanced Malloc exploits

http://msdn.microsoft.com/en-us/magazine/cc534993.aspx (Large Object Heap Uncovered)

http://msdn.microsoft.com/en-us/library/aa970850.aspx (Weak Event Patterns)

Ronn Black [email protected]