InsidetheGarbageCollector
2
Agenda
• ApplicationsandResources• TheManagedHeap• MarkandCompact• Generations• Non-MemoryResources• Finalization• HinderingtheGC• HelpingtheGC
3
ApplicationsandResources
• Applicationsusemanydifferentkindsofresourceswhenexecuting– Memory– Filehandles– Databaseconnections– Sockets
• .NETprovidesinfrastructureandpatternsformanaginganapplicationsresources
4
MemoryandtheManagedHeap
• .NEThasspecificfunctionalitytoautomatememorymanagement– Applicationsrequestmemoryusingnewkeyword– MemoryisallocatedinareacalledtheManagedHeap
• RuntimecleansupmemorywhennecessaryusingGarbageCollection (GC)– Onlymanagedheapisgarbagecollected.Unmanagedandstack
allocatedmemoryunaffected– GarbageCollectorremovesobjectsnolongerinuse
5
HowtheGarbageCollectorWorks
• Applicationsrunasifmemoryisinfinite• GCisinvokedwhenresourcethresholdbreached• Assumesallobjectsaregarbage• Collectsthosenotinuse
A B C D E F B D E G
6
WhatObjectsareinUse?
• Thegarbagecollectordoesnotcollectobjectsinuse– Howdoesitknowwhatisinuseandwhatisnot?
• GChasconceptofobjectsbeingreachable– Objectsthatcouldbeaccessedfromcodethatisyettorun
• GCwalksobjectsgraphunderliveroots– Non-nullstaticreferences– Localvariablesonthestackthatarestillinuse– Afewmoreexotickinds,e.g.thenativecodeinterop infrastructure
• AnyobjectreachablefromaliverootsurvivestheGC
7
SpottheLiveRoots
• WhatreferencesareliverootswhentheGCruns?
static object o1 = new object();
void RunTest(){object o2 = new object();object o3 = new object();
GC.Collect();
o1 = null;
GC.Collect();
ProcessObject(o3);
GC.Collect();}
Whatisgarbagehere?
Whatisgarbagehere?
Whatisgarbagehere?
8
GCOptimization- Generations
• ExaminingtheentireheapeveryGCtooexpensive– Optimization:ifobjectsurvivedlastGCthenprobablystillalive– Bydefaultonlychecksthemostrecentlyallocatedobjects
• .NETGCisGenerational– Threegenerations– Allobjectsallocatedintogen0– Anyobjectsurvivingacollectionispromotedtonextgeneration
A B C D E F B D E G
Gen0 Gen1 Gen0
GC
9
TheImplicationsofGenerations
• RelativecostofGC– Gen0isverycheaptocollect– Gen1ismoreexpensivetocollectthatgen0– Gen2canbeveryexpensivetocollect
• HealthyGC– Orderofmagnitudebetweennumberofcollectionsofeachsuccessive
generationregardedashealthy– gen0:gen1:gen2=>100:10:1
• Generallydon’ttrytosecondguesstheGC
10
GCOptimization– GCStyles
• ThreestylesofGC– Non-concurrent– Concurrent– Asynchronous
11
ConcurrentandNon-Concurrent
• Non-concurrent– GCstartsandrunsthroughtocompletionwithoutinterruption– AlwaysusedforGen0andGen1collects
• Concurrent– Applicationthreadsinterleavedwithcollection– Keepsapplicationresponsive– OnlyusedforsomeGen2collects– CancontinueapplicationexecutionuntilanotherGCrequired
12
Async
• Asynchronous– Introducedinversion4.0– Similartoconcurrentbutcanperformgen0andgen1collectsduringa
gen2collect
13
ConcurrentGC
Gen2GCThread
ApplicationThread
ThreadSuspended
new()
new()
new()
Allocation requires Gen0 collect
Gen 2 collection complete
14
BackgroundGC
Gen2GCThread
ApplicationThread
ThreadSuspended
new()
new()
new()
Allocation requires Gen0 collect
Gen 2 collection complete
15
GCModes
• TherearethreeGCmodes– WorkstationConcurrent(default)– WorkstationNon-Concurrent– Server
• Controlledbyconfig flags<configuration>
<runtime><gcServer enabled="true"/><gcConcurrent enabled="false"/>
</runtime></configuration>
16
WorkstationConcurrent
• DesignedtokeepUIapplicationsinteractive– UIthreadpausedasshortatimeaspossible
• Gen0andGen1usenon-concurrentGC– UIthreadpausetimewouldbeinsignificant
• Gen2canuseconcurrent– Gen2canbeexpensive– KeepsUIthreadpumpingthemessagequeue
• Gen2canuseasynchronous– MeansUIthreadstaysfree-runningevenifanotherGCisrequired– Onlyavailableon.NET4.0andlater
17
Workstationnon-concurrent
• WholeGCisnon-concurrent– Optimizedfornon-UIcode– GCkidnapsallocatingthread– FewerCPUcyclesthanworkstationconcurrent
18
ServerGC
• Tunedformultipleprocessors– Eachprocessorgetsownblockofmanagedheapforallocation/GC
calledarena– Allowslockfreeallocationacrossmultiplecores
• Alwaysnon-concurrent– GCtakesplaceonallprocessorsatthesametime
19
GCOptimization– SelfTuning
• GCbehavior dependentonyourapplication– Usesheuristicstoworkoutefficientstrategy– IfGCofagenerationiseffectivethenperformsmore– IfGCofagenerationreclaimslittlememorythenperformsless
• GCselftuningnormallyproducesoptimalresults– Beststrategyforyourapplication
• AvoidGC.Collect– DisruptsGCstatisticsandsoselftuninglesseffective
20
LargeObjects
• Movinglargeobjectstooexpensive– Largeobjectover85000bytes
• AllocatedinLargeObjectHeap
21
MemoryisnottheonlyResource
• Onlymemorymanagementisautomated– Runtimedoesnotknowwhenuseofotherresourcesiscomplete
• Typesthatcontrolnon-memoryresourcesfollowstandardpattern– ImplementIDisposable– ConsumercallsDisposewhentheyarefinishedpublic interface IDisposable{
void Dispose();}
22
WhenShouldYouImplementIDisposable?
• MostclassesdonotneedtoimplementIDisposable– Donotconsumeresourcesotherthanmemory
• ClassesthatdirectlycontrolresourcesacquiredviainteropmustimplementIDisposable– Noothermanagedtypecanreleasethoseresources
• ClassesthataggregateothertypesthatimplementIDisposable shouldimplementIDisposable themselves– ProvidesahooktoDisposeaggregatedobjects
23
WhatifIdon’tCallDispose?
• Onlyanissuefortypesthatdirectlycontrolunmanagedresources– FileStream– SqlConnection– Icon
• Needlastchancemechanismforfreeingupresources– Nooneelsecanfreeupresources
• RuntimehasconceptofFinalization– Veryunlikelythatyourclasseswillneedafinalizer
24
HowFinalizationWorks
• TypesthatsupportfinalizationoverrideFinalizevirtualmethodonSystem.Object– C#syntaxlookslikeaC++destructor
• Runtimeseestypehasfinalizer wheninstantiated– Putsobjectinfinalizationqueue
class SharedMemory{
~SharedMemory(){}
}
25
FinalizationandGC
• WhenGCdecidestocollectobjectitseesit’sfinalizable– Movestheobjectontofreachable queue– freachable queueactsasliveroot(finalizationreachable)
• Separatefinalizationthreadprocessesfreachable queue– Callsfinalizer andremovesobjectfromqueue– ObjectcanbecollectednexttimeGClooksatit
26
ConsequencesofFinalization
• Finalizable objectswillalwayssurviveoneGC– Alwayspromotedtogen1orgen2– Consequentlymoreexpensivetocollect
• Timingoffinalizer executionnon-deterministic– AfterGCnoticesitisgarbage– WhenFinalizationthreadgetsroundtoit
• Limitedfunctionalityinfinalizer– Shouldnotcallotherobjectsasmayalreadyhavebeenfinalized
• Finalizable classesshouldalwaysimplementIDisposable– Cansuppressfinalization inDispose
public void Dispose(){
GC.SuppressFinalize(this);}
27
HinderingandHelpingtheGC
• ThreemainissuesforGC– Unnecessarypromotion– Referenceheavydatastructures– Pinning
28
UnnecessaryPromotion
• WanttominimiseGen2collections– IdeallyallGen2objectsliveforever– Notrealistic
• Promotethendieisworstscenario– Badlytunedcaches– Finalizers– “ad-hoc”caching– Notreleasingdeadobjects
29
UnnecessaryPromotion
• Tunecachetimeouts– DropcacheinGen1– Makeitlonglivedtomakethehitworthwhile
• Removeunnecessaryfinalizers– IfabsolutelyrequiredrefactorcodeintoSafeHandle
public abstract class SafeHandle : CriticalFinalizerObject,IDisposable
{...
}
30
“Ad-hoc”Caching
• ConsiderWeakReference– ObjectaccessibleunlessGC’d
“ProbablyneedthisobjectagainsoonsoI’llhangontoit”
WeakReference wr = new WeakReference(new object());
object temp = wr.Target;if(temp == null){
Console.WriteLine("Collected");}else{
Console.WriteLine("Still alive");}
31
HangingontoDeadObjects
• Setmemberandstaticreferencestonullwhendone– GCcancleanupassoonaspossible
• Especiallyimportantwhenreplacingobject– Becarefulofthreadingissues
class ReferenceData{
XElement data;
public void ReloadData(string filename){
data = null;data = XElement.Load(filename);
}}
32
ReferenceHeavyStructures
• Markphasemadeharderbymanyreferences– GChastochasedownembeddedobjectgraphs
• Thinkofrevisedoroptimisedwaysofrepresentingdata– Arrays– AdjacencyMatrices
• Example:ThreadPoolQueuebefore4.0
33
ThreadPoolQueueBefore4.0
• Linkedlistofworkitems– Rootisnevergarbage– Lotsofwork=lotsofreferences
Node WorkItem
Node WorkItem
Node WorkItem
34
ThreadPoolQueueAfter4.0
• Linkedlistofarraysofworkitems– Lotsofwork=fewreferences
WorkItem
WorkItem
WorkItem
WorkItem
WorkItem
WorkItem
35
Pinning
• PinningmeansGCcan’tmoveobject– Requiredininterop scenarios
• ConsiderinflatinglargebufferstobeallocatedinLOH– PinningirrelevantinLOH– ReuseLOHbuffers
36
Summary
• GCautomatesmemoryreclamation• GCisheavilyoptimized• ReleasemodeGCmuchmoreaggressivethandebug• NonmemoryresourcesfreedupusingIDisposable pattern• Finalizationexistsasalastresortforframeworkclasses.You
shouldnotneeditinyourcode• YoucanhelptheGC• YoucanhindertheGC