Consider • Starting with 160 k of memory do: • Allocate p1 (50 k) • Allocate p2 (30 k) • Allocate p3 (40 k) • Free p2 • Allocate p4 (40 k) • Free p3 • Allocate p5 (60 k) • Free p1 • Allocate p6 (30k)
Memory Allocation Algorithms Design YOUR algorithm for allocation and deallocation of memory
Memory Management • Dynamic (heap) • Significant issues • Significant execution time (16%) • Memory performance not uniform • Allocation policies • Bugs • Dereference problems • Memory leaks
Memory Allocation Strategies • Explicit vs. Implicit Memory Allocator • General purpose vs. custom allocator • Software vs. hardware
Allocation Examples p1 = malloc(4) p2 = malloc(5) p3 = malloc(6) free(p2) p4 = malloc(2)
Goals of Good malloc/free • Good execution-time performance • Good space utilization • Good locality properties
Fragmentation • Poor memory utilization --- fragmentation • Internal – overhead associated with a block of memory • External – have enough blocks of memory for a request, but not contiguous Internal fragmentation Space in use
External Fragmentation p1 = malloc(4) p2 = malloc(5) p3 = malloc(6) free(p2) p4 = malloc(6) External fragmentation depends on future requests; thus difficult to anticipate
Bidirectional Coalescing • Boundary tags [Knuth73] • Replicate size/allocated word at bottom of free blocks • Allows us to traverse the “list” backwards, but requires extra space • Important and general technique!
Boundary Tags 1 word a = 1: allocated block a = 0: free block size: total block size Application memory (allocated blocks only) Header size a Application Memory (and padding?) Format of allocated and free blocks Boundary tag (footer) size a 4 4 4 4 6 6 4 4
Your turn • Using boundary tag data structure, define algorithms for: • Allocation • Free
Key Allocator Policies • Placement policy: • First fit, next fit, best fit, etc. • Trades off lower throughput for less fragmentation • Splitting policy: • When do we go ahead and split free blocks? • How much internal fragmentation are we willing to tolerate? • Coalescing policy: • Immediate coalescing: coalesce adjacent blocks each time free is called • Deferred coalescing: try to improve performance of free by deferring coalescing until needed. e.g.,
Refinements • Separate lists • Binary buddy • Lea allocator • Custom allocators
Lea Allocator • An approximate best-fit allocator with different behavior based on object size • Small Objects (<64 bytes) allocated by exact-size quicklists • Medium Objects (<128K) – coalesce quicklists • Large Objects – allocate and free by mmap • The best allocator known
Why programmers use Custom Allocators? • Improving runtime performance • Reducing memory consumption • Improving software engineering (?)
Alternative Memory Management • Region (arenas) • Reserve memory blocks for program “parts” • Deallocate entire regions, not per allocation • Garbage collection • Programmer allocates but doesn’t free • “System” keeps track of memory “pointed to” locations, removes the rest • Java
Why Garbage Collect at All? • Safety • Memory leaks • Continued use of freed pointers • Simplicity • Correctness • Programming ease
The Two-Phase Abstraction • 1. Detection • 2. Reclamation
Liveness and Garbage • There is a root set which is defined as live. • Anything reachable from a live pointer is also live • Everything else is garbage
The Root Set • The Root Set • Static global and module variables • Local Variables • Variables on any activation stack(s) • Everyone else • Anything Reachable From a live value
Reference Counting • Each allocated chunk has reference count that shows how many locations point (refer) to this one. • Advantages ??? • Disadvantages ???
Mark-Sweep Collection • Starting from the root set traverse all pointers via depth/breadth first search. • Free everything that is not marked.