memory management
play

Memory Management eg C: { double* A = malloc(sizeof(double)*M*N); - PDF document

2/11/2008 Motivation Recall unmanaged code Memory Management eg C: { double* A = malloc(sizeof(double)*M*N); Mingsheng Hong for(int i = 0; i < M*N; i++) { A[i] = i; CS 215, Spring 2008 } } Whats wrong? memory leak:


  1. 2/11/2008 Motivation  Recall unmanaged code Memory Management  eg C: { double* A = malloc(sizeof(double)*M*N); Mingsheng Hong for(int i = 0; i < M*N; i++) { A[i] = i; CS 215, Spring 2008 } }  What’s wrong?  memory leak: forgot to call free(A);  common problem in C Motivation System.GC  Solution: no explicit malloc/free  Can control the behavior of GC  eg. in Java/C#  not recommend in general {  sometimes useful to give hints double[] A = new double[M*N]; for(int i = 0; i < M*N; i++) {  Some methods: A[i] = i;  Collect } }  Add/RemoveMemoryPressure  No leak: memory is “lost” but freed later  ReRegisterFor/SuppressFinalize  A Garbage Collector tries to free memory  WaitForPendingFinalizers  keeps track of used information somehow Finalizers Destructors  protected virtual void Finalize()  Finalizers cannot be overridden  Instead, write a class destructor ~Classname()  Finalizers are called nondeterministically  Destructors are called bottom-up  During the garbage collection process  When the GC.Collect method is called public class A { ~A() { Console.WriteLine("A d’tor"); }  When the CLR is shutting down  Can be suppressed by GC.SuppressFinalize } public class B : A {  Current thread can wait with GC.WaitForPendingFinalizers ~B() { Console.WriteLine(“B d’tor"); } }  A a = new B(); //program then shuts down 1

  2. 2/11/2008 Finalizers are Expensive IDisposable  IDispose declares void Dispose()  Finalization in GC:  When object with Finalize method created  Can be explicitly invoked public class A: IDisposable {  add to Finalization Queue  public A() { // Allocate resources }  First GC: moved to Freachable queue public void Dispose() { // Release resources }  After finalizer is called, memory released in a } future GC A disposableobject=null;  try { disposableobject=new A(); }  One single thread to call finalizers finally {  At least 2 GC cycles needed disposableobject.Dispose(); disposableobject=null; } The using Statement Weak References  using calls Dispose automatically  Sometimes want to keep references but not cause the GC to wait using(A disposableobject= new A()) {  A a = new A(); // use object WeakReference wr = new WeakReference(a); }  Now a can be collected  Can declare multiple objects  wr.Target is null if referenced after a collected using(A a1 = new A(), a2 = new A())  Usage using(B b1 = new B()) {  Large objects  infrequently accessed // use objects  nice to have but can be regenerated }  Handles to strings in a string table Object Pinning Soundness and Completeness  Can require that an object not move  For any program analysis  could hurt GC performance  Sound?  useful for unsafe operation  are the operations always correct?  usually an absolute requirement  in fact, needed to make pointers work  Complete?  syntax:  does the analysis capture all possible instances?  fixed(…) { … }  For Garbage Collection  will not move objects in the declaration in the  sound = does it ever delete current memory? block  complete = does it delete all unused memory? 2

  3. 2/11/2008 Reference Counting Reference Counting  Keep count of references  Disadvantages  on assignment, increment (and decrement)  can’t detect cycles  when removing variables, decrement  constant cost, even when lots of space  eg. local variables being removed from stack  optimize the common case!  at ref count 0, reclaim object space  Advantage: incremental (don’t stop)  Is this safe? 2 1  Yes: not reference means not reachable 1 1 Reachable Reachability Graph Reachability Graph  Instead of counting references  Top-level objects (roots)  keep track of some top-level objects  managed by CLR  and trace out the reachable objects  local variables on stack  only clean up heap when out of space  registers pointing to objects  much better for low-memory programs  Garbage collector starts top-level  Two major types of algorithm  builds a graph of the reachable objects  Mark and Sweep  Copy Collectors Mark and Sweep Copy Collectors  Instead of just marking as we trace  Two-pass algorithm  First pass: walk the graph and mark all objects  copy each reachable object to new part of heap  everything starts unmarked  needs to have enough space to do this  Second pass: sweep the heap, remove unmarked  no need for second pass  not reachable implies garbage  Advantages  Soundness?  one pass  Yes: any object not marked is not reachable  compaction  Completeness?  Disadvantages  Yes, since any object unreachable is not marked  higher memory requirements  But only complete eventually 3

  4. 2/11/2008 Compacting Copy Collector Compacting Copy Collector  Move live objects to bottom of heap  Another possible collector:  leaves more free space on top  divide memory into two halves  contiguous allocation allows faster access  fill up one half before doing any collection  cache works better with locality  on full:  Must then modify references  walk the graph and copy to other side  work from new side  recall: references are really pointers  Need twice memory of other collectors  must update location in each object  But don’t need to find space in old side  contiguous allocation is easy Fragmentation Heap Allocation Algorithms  best-fit  Common problem in memory schemes  search the heap for the closest fit  Enough memory but not enough contiguous  takes time  consider allocator in OS  causes external fragmentation (as we saw)  first-fit  choose the first fit found 10 10?  starts from beginning of heap 10 5  next-fit  first-fit with a pointer to last place searched 15 10 5 C# Memory management Generations  Current .NET uses 3 generations:  Related to next-fit, copy-collector  0 – recently created objects: yet to survive GC  keep a NextObjPointer to next free space  1 – survived 1 GC pass  use it for new objects until no more space  2 – survived more than 1 GC pass  Keep knowledge of Root objects  During compaction, promote generations  global and static object pointers  eg. Gen 1 reachable object goes to Gen 2  all thread stack local variables  Assumption: longer lived implies live longer  registers pointing to objects  Valid for many applications  maintained by JIT compiler and runtime  eg. JIT keeps a table of roots 4

  5. 2/11/2008 C# Garbage Collectors  Workstation GC  Concurrent GC  Non-concurrent GC  Server GC  Optimize for throughput, not response time 5

Recommend


More recommend