Deep dumpster diving 2010

Preview:

Citation preview

DEEP DUMPSTER DIVING

A close look at .Net garbage collection

Ronn Black

October 2010

Why should I care?

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");

}

}

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

Unmanaged Memory Management

Unused AreaHi Address

Low Address

ReservedReserved

Args & VariablesArgs & Variables

StackStack

HeapHeap

Stack PointerUnused Area

NextObjPtr

NextObjPtr

RootsRoots

NextObjPtr

RootsRoots

NextObjPtr

~MyClass(){

//Do work here…}

MyClass.Finalize(){

//Do work here…}

=

Finalizers

RootsRoots

F

G

A

B

C

E

H

I

DFreachable Queue

C

E

F

I

Finalization Queue

F

G (x)

A

RootsRoots

B (x)

C

E (x)

H (x)

I (x)

DFreachable Queue

C

E (x)

F

I (x)

Finalization Queue

F

A

RootsRoots

C

E (x)

I (x)

D

E (x)

I (x)

Freachable Queue

C

F

Finalization Queue

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.

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??

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??

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??

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");

}

}

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();

}

Usingusing System;

using System.Collections.Generic;

using System.Diagnostics;

Usingusing System;

using System.Collections.Generic;

using System.Diagnostics;

using (MyClass c = new MyClass())

{

//Do Some Work

}

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");

}}

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

Design patterns and Memory

Design patterns and MemoryCircular References.

Form

+ControlsControl

+Parent

Control

+Parent

Control

+Parent

Control

+Parent

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;

}

Design patterns and MemoryRooted objects (Singletons).

Form

+ControlsControl

+Parent

Control

+Parent

Control

+Parent

Control

+Parent

Preferences

$GetPrefs+PrefsChanged

Design patterns and MemoryLists, Hashtables, Dictionaries, etc.

List<T>

Control

+Parent

Control

+Parent

Control

+Parent

T

Design patterns and Memory

public class Foo

{

public static void DoSomething()

{

List<Bar> bars;

...

//Do Something

bar.Clear();

}

}

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());

...

}

}

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

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 rblack@btsoft.org