Dynamic Memory Allocation
Agenda Process Layout Memory Allocation Algorithms Garbage Collection Algorithms Reference: Ch. 5.7 and 8.5
Process Layout lower addresses executable code (text) static data (e.g. globals) heap stack higher addresses
Process Layout lower addresses executable code (text) addresses static data (e.g. globals) addresses valid heap addresses valid stack higher addresses
Process Layout lower addresses executable code (text) rigid addresses static data (e.g. globals) addresses valid rigid heap changed with sbrk() changed by calling and returning from functions addresses valid stack higher addresses
sbrk() #include <unistd.h> Prototype: void *sbrk(ptrdiff_t increment); Increases or decreases the address of the bottom of the heap Returns the previous address sbrk(0) can be used to obtain the current address Implementation of sbrk() is operating system dependent
Example Compiled on tux using gcc, this program produces the following output: 0x00020908 0x00022908 #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main() { printf("0x%08p\n",sbrk(0)); malloc(1024); return 0; }
What happened… Initially, the heap ended at 0x00020908 executable code (text) static data (e.g. globals) 0x00020908 stack
What happened… Initially, the heap ended at 0x00020908 Then I said that I needed an additional 1k executable code (text) static data (e.g. globals) 0x00020908 stack
What happened… Initially, the heap ended at 0x00020908 Then I said that I needed an additional 1k So malloc() increased the heap size by 8k executable code (text) static data (e.g. globals) 0x00020908 0x00022908 stack
Agenda Process Layout Memory Allocation Algorithms Fixed Size Variable Size First-Fit Next-Fit Best-Fit The Buddy Algorithm Garbage Collection Algorithms
Fixed Size Algorithm Maintain a list of free blocks (the free-list) To allocate a block, pop one off the front of the list To free a block, push it back onto the front of the list
Fixed Size Algorithm Obtain a large chunk of memory
Fixed Size Algorithm Divide it up into blocks of the appropriate size
Fixed Size Algorithm Give each of the blocks a four-byte header
Fixed Size Algorithm front Use these headers as next-pointers, and arrange the blocks into a linked list
Fixed Size Algorithm front To allocate a block, pop one off the front of the list, e.g. p1 = alloc(); p2 = alloc(); p3 = alloc();
Fixed Size Algorithm front p1 To allocate a block, pop one off the front of the list, e.g. p1 = alloc(); p2 = alloc(); p3 = alloc();
Fixed Size Algorithm front p1 p2 To allocate a block, pop one off the front of the list, e.g. p1 = alloc(); p2 = alloc(); p3 = alloc();
Fixed Size Algorithm front p1 p2 p3 To allocate a block, pop one off the front of the list, e.g. p1 = alloc(); p2 = alloc(); p3 = alloc();
Fixed Size Algorithm front p1 p2 p3 To free a block, push it back onto the front of the list, e.g. free(p1); free(p3); free(p2);
Fixed Size Algorithm front p1 p2 p3 To free a block, push it back onto the front of the list, e.g. free(p1); free(p3); free(p2);
Fixed Size Algorithm front p1 p2 p3 To free a block, push it back onto the front of the list, e.g. free(p1); free(p3); free(p2);
Fixed Size Algorithm front p1 p2 p3 To free a block, push it back onto the front of the list, e.g. free(p1); free(p3); free(p2);
Note that the list is not usually Fixed Size Algorithm front Note that the list is not usually kept sorted by address
Agenda Process Layout Memory Allocation Algorithms Fixed Size Variable Size First-Fit Next-Fit Best-Fit The Buddy Algorithm Garbage Collection Algorithms
Variable Size Algorithms* Maintain a list of free blocks (the free-list) To allocate a block, find a block of sufficient size and remove it from the list To free a block, insert it into the list, keeping the list sorted by address * The Buddy Algorithm does not adhere to this overall scheme.
Variable Size Algorithms Both free and allocated blocks have headers The composition of the headers will vary with the implementation Example user data Free Block: Allocated Block: unused size next free block size
Variable Size Algorithms From the memory manager’s perspective, the block starts before the headers user data Allocated Block: size From the user’s perspective, the block starts after the headers
Variable Size Algorithms Adjacent free blocks must be coalesced unused unused 4k next free block 8k next free block unused 12k next free block
Finding a block of sufficient size At least three approaches First-Fit Find the first block in the list of sufficient size Next-Fit Best-Fit
Variable Size: First-Fit front 16k Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: First-Fit front 2k 14k p1 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: First-Fit front 2k 1k 13k p1 p2 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: First-Fit front 2k 1k 5k 8k p1 p2 p3 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: First-Fit front 2k 1k 5k 1k 7k p1 p2 p3 p4 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: First-Fit front 2k 1k 5k 1k 4k 3k p1 p2 p3 p4 p5 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: First-Fit front 2k 1k 5k 1k 4k 1k 2k p1 p2 p3 p4 p5 p6 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: First-Fit front 2k 1k 5k 1k 4k 1k 2k p1 p2 p3 p4 p5 p6 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: First-Fit front 2k 1k 5k 1k 4k 1k 2k p1 p2 p3 p4 p5 p6 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: First-Fit front 2k 1k 5k 1k 4k 1k 2k p1 p2 p3 p4 p5 p6 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: First-Fit front 2k 1k 3k 2k 1k 4k 1k 2k p1 p2 p7 p4 p5 p6 p3 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: First-Fit front Coalesced 2k 1k 3k 2k 1k 7k p1 p2 p7 p4 p5 p6 p3 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: First-Fit front 1k 1k 1k 3k 2k 1k 7k p8 p2 p7 p4 p5 p6 p1 p3 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: First-Fit front 1k 1k 1k 3k 2k 1k 6k 1k p8 p2 p7 p4 p9 p6 p1 p3 p5 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Finding a block of sufficient size At least three approaches First-Fit Next-Fit There is an additional pointer into the free-list called the roving pointer The search starts at the block pointed to by the roving pointer Once a block is found, the roving pointer is pointed to the next block in the free-list Best-Fit
Variable Size: Next-Fit front rp 16k Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: Next-Fit front rp 2k 14k p1 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: Next-Fit front rp 2k 1k 13k p1 p2 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: Next-Fit front rp 2k 1k 5k 8k p1 p2 p3 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: Next-Fit front rp 2k 1k 5k 1k 7k p1 p2 p3 p4 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: Next-Fit front rp 2k 1k 5k 1k 4k 3k p1 p2 p3 p4 p5 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: Next-Fit front rp 2k 1k 5k 1k 4k 1k 2k p1 p2 p3 p4 p5 p6 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: Next-Fit front rp 2k 1k 5k 1k 4k 1k 2k p1 p2 p3 p4 p5 p6 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: Next-Fit front rp 2k 1k 5k 1k 4k 1k 2k p1 p2 p3 p4 p5 p6 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: Next-Fit front rp 2k 1k 5k 1k 4k 1k 2k p1 p2 p3 p4 p5 p6 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: Next-Fit front rp 2k 1k 3k 2k 1k 4k 1k 2k p1 p2 p7 p4 p5 p6 p3 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: Next-Fit front rp Coalesced 2k 1k 3k 2k 1k 7k p1 p2 p7 p4 p5 p6 p3 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: Next-Fit front rp 2k 1k 3k 1k 1k 1k 7k p1 p2 p7 p8 p4 p5 p6 p3 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: Next-Fit front rp 2k 1k 3k 1k 1k 1k 6k 1k p1 p2 p7 p8 p4 p9 p6 p3 p5 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Finding a block of sufficient size At least three approaches First-Fit Next-Fit Best-Fit Find the smallest block in the list of sufficient size
Variable Size: Best-Fit front 16k Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: Best-Fit front 2k 14k p1 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: Best-Fit front 2k 1k 13k p1 p2 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: Best-Fit front 2k 1k 5k 8k p1 p2 p3 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: Best-Fit front 2k 1k 5k 1k 7k p1 p2 p3 p4 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: Best-Fit front 2k 1k 5k 1k 4k 3k p1 p2 p3 p4 p5 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: Best-Fit front 2k 1k 5k 1k 4k 1k 2k p1 p2 p3 p4 p5 p6 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: Best-Fit front 2k 1k 5k 1k 4k 1k 2k p1 p2 p3 p4 p5 p6 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: Best-Fit front 2k 1k 5k 1k 4k 1k 2k p1 p2 p3 p4 p5 p6 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: Best-Fit front 2k 1k 5k 1k 4k 1k 2k p1 p2 p3 p4 p5 p6 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: Best-Fit front 2k 1k 5k 1k 3k 1k 1k 2k p1 p2 p3 p4 p5 p6 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: Best-Fit front Coalesced 2k 1k 5k 1k 3k 4k p1 p2 p3 p4 p5 p6 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: Best-Fit front 1k 1k 1k 5k 1k 3k 4k p8 p2 p3 p4 p5 p6 p1 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k);
Variable Size: Best-Fit front 1k 1k 1k 5k 1k 3k 4k p8 p2 p3 p4 p5 p6 p1 Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); p6 = alloc(1k); free(p1); free(p3); free(p5); p7 = alloc(3k); free(p6); p8 = alloc(1k); p9 = alloc(6k); FAIL!
Summary of the three approaches First-Fit Bad if you get a cluster of small blocks at the front of the free-list Best-Fit Visits every free block during an allocation Tends to leave a lot of small blocks in the free-list Next-Fit Generally considered the best of the three
Agenda Process Layout Memory Allocation Algorithms Fixed Size Variable Size First-Fit Next-Fit Best-Fit The Buddy Algorithm Garbage Collection Algorithms
The Buddy Algorithm The size of all blocks (both free and allocated) are powers of 2 Wastes a lot of space But makes the algorithm much faster
A block’s buddy A block may or may not have a buddy A block and its buddy are always the same size If a block of size 2k resides at binary address …000…0 then its buddy (if it has one) resides at binary address …100…0 k 0’s k-1 0’s
The Buddy Algorithm There is one free-list for each size of block The lists are doubly-linked The lists are not kept sorted by address
The Buddy Algorithm To allocated a block of size n Determine the smallest integer k such that 2k ≥ n Find a block of size 2k, and remove the block from its free-list If there are no blocks of size 2k Find the next larger block, and remove it from its free-list Divide the block into two buddies Keep one and insert the other into the appropriate free-list Continue in this manner until you have a block of size 2k
The Buddy Algorithm To deallocate a block of size 2k Check the block’s buddy If they are both free, coalesce them into one block of size 2k+1 Continue in this manner until you cannot coalesce any more blocks Insert the block that you are left with into the appropriate free-list
The Buddy Algorithm Free Block: Allocated Block: user data unused logarithmic size forward pointer back pointer allocated? logarithmic size
The Buddy Algorithm Example: 16k: 16k 8k: 4k: 2k: 1k: p1 = alloc(2k); free(p2); free(p4); free(p3); p6 = alloc(3k); p7 = alloc(3k); free(p5); free(p6); free(p1); free(p7);
The Buddy Algorithm Example: 16k: 8k: 8k 4k: p1 4k 2k: 2k 2k 1k: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); free(p2); free(p4); free(p3); p6 = alloc(3k); p7 = alloc(3k); free(p5); free(p6); free(p1); free(p7);
The Buddy Algorithm Example: 16k: 8k: 8k 4k: p1 4k 2k: 2k p2 1k: 1k 1k p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); free(p2); free(p4); free(p3); p6 = alloc(3k); p7 = alloc(3k); free(p5); free(p6); free(p1); free(p7);
The Buddy Algorithm Example: 16k: p3 8k: 5k 3k 4k: p1 4k 2k: 2k p2 1k: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); free(p2); free(p4); free(p3); p6 = alloc(3k); p7 = alloc(3k); free(p5); free(p6); free(p1); free(p7);
The Buddy Algorithm Example: 16k: p3 8k: 5k 3k 4k: p1 4k 2k: 2k p2 p4 p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); free(p2); free(p4); free(p3); p6 = alloc(3k); p7 = alloc(3k); free(p5); free(p6); free(p1); free(p7);
The Buddy Algorithm Example: 16k: p3 8k: p5 5k 3k 4k: p1 4k 2k: 2k p2 p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); free(p2); free(p4); free(p3); p6 = alloc(3k); p7 = alloc(3k); free(p5); free(p6); free(p1); free(p7);
The Buddy Algorithm Example: 16k: p3 8k: p5 5k 3k 4k: p1 4k 2k: 2k p4 p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); free(p2); free(p4); free(p3); p6 = alloc(3k); p7 = alloc(3k); free(p5); free(p6); free(p1); free(p7);
The Buddy Algorithm Example: 16k: p3 8k: p5 5k 3k 4k: p1 4k 2k: 2k 2k Coalesced Example: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); free(p2); free(p4); free(p3); p6 = alloc(3k); p7 = alloc(3k); free(p5); free(p6); free(p1); free(p7);
The Buddy Algorithm Example: 16k: 8k: p5 8k 4k: p1 4k 2k: 2k 2k 1k: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); free(p2); free(p4); free(p3); p6 = alloc(3k); p7 = alloc(3k); free(p5); free(p6); free(p1); free(p7);
The Buddy Algorithm Example: 16k: 8k: p5 p6 4k: p1 4k 3k 1k 4k 2k: 2k p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); free(p2); free(p4); free(p3); p6 = alloc(3k); p7 = alloc(3k); free(p5); free(p6); free(p1); free(p7);
The Buddy Algorithm Example: 16k: 8k: p5 p6 p7 4k: p1 4k 3k 1k 3k 1k p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); free(p2); free(p4); free(p3); p6 = alloc(3k); p7 = alloc(3k); free(p5); free(p6); free(p1); free(p7);
The Buddy Algorithm Example: 16k: 8k: p6 p7 4k: p1 4k 3k 1k 3k 1k 2k: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); free(p2); free(p4); free(p3); p6 = alloc(3k); p7 = alloc(3k); free(p5); free(p6); free(p1); free(p7);
The Buddy Algorithm Example: 16k: 8k: p7 4k: p1 4k 4k 3k 1k 2k: 2k 2k p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); free(p2); free(p4); free(p3); p6 = alloc(3k); p7 = alloc(3k); free(p5); free(p6); free(p1); free(p7);
The Buddy Algorithm Example: 16k: 8k: 8k p7 4k: 4k 3k 1k Coalesced 2k: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); free(p2); free(p4); free(p3); p6 = alloc(3k); p7 = alloc(3k); free(p5); free(p6); free(p1); free(p7);
The Buddy Algorithm Example: 16k: 16k 8k: Coalesced 4k: 2k: 1k: p1 = alloc(2k); p2 = alloc(1k); p3 = alloc(5k); p4 = alloc(1k); p5 = alloc(4k); free(p2); free(p4); free(p3); p6 = alloc(3k); p7 = alloc(3k); free(p5); free(p6); free(p1); free(p7);
Agenda Process Layout Memory Allocation Algorithms Garbage Collection Algorithms Reference Counting Mark-and-Sweep
Garbage Collection Automatically determining at runtime when an object may be deallocated
Reference Counting Every object is given an additional integer field At any point in time, this field holds the total number of references to the object When a reference is redirected to the object, the field is incremented When a reference is redirected away from the object, the field is decremented When the field becomes zero, the object is deallocated
Reference Counting Example: p1: p2: p3: p1 = new …; p1->f = new …; p1->g = new …; p2 = p1; p3 = p1->g; p1 = NULL; p2 = NULL;
Reference Counting Example: Count: 1 p1: f: g: p2: p3: p1 = new …; p1->f = new …; p1->g = new …; p2 = p1; p3 = p1->g; p1 = NULL; p2 = NULL;
Reference Counting Example: 1 Count: Count: 1 p1: f: g: p2: p3: p1 = new …; p1->f = new …; p1->g = new …; p2 = p1; p3 = p1->g; p1 = NULL; p2 = NULL;
Reference Counting Example: 1 Count: 1 Count: p1: f: g: p2: 1 Count: p1 = new …; p1->f = new …; p1->g = new …; p2 = p1; p3 = p1->g; p1 = NULL; p2 = NULL;
Reference Counting Example: 2 Count: 1 Count: p1: f: g: p2: 1 Count: p1 = new …; p1->f = new …; p1->g = new …; p2 = p1; p3 = p1->g; p1 = NULL; p2 = NULL;
Reference Counting Example: 2 Count: 1 Count: p1: f: g: p2: 2 Count: p1 = new …; p1->f = new …; p1->g = new …; p2 = p1; p3 = p1->g; p1 = NULL; p2 = NULL;
Reference Counting Example: 1 Count: 1 Count: p1: f: g: p2: 2 Count: p1 = new …; p1->f = new …; p1->g = new …; p2 = p1; p3 = p1->g; p1 = NULL; p2 = NULL;
Reference Counting Example: Count: 1 Count: p1: f: g: p2: 2 Count: p3: Count: 1 Count: p1: f: g: p2: 2 Count: p3: Example: p1 = new …; p1->f = new …; p1->g = new …; p2 = p1; p3 = p1->g; p1 = NULL; p2 = NULL;
Reference Counting Example: Count: Count: p1: f: g: p2: 1 Count: p3: Count: Count: p1: f: g: p2: 1 Count: p3: Example: p1 = new …; p1->f = new …; p1->g = new …; p2 = p1; p3 = p1->g; p1 = NULL; p2 = NULL;
Reference Counting Example: Count: Count: p1: f: g: p2: 1 Count: p3: Count: Count: p1: f: g: p2: 1 Count: p3: Example: p1 = new …; p1->f = new …; p1->g = new …; p2 = p1; p3 = p1->g; p1 = NULL; p2 = NULL;
Reference Counting p1: Example: p1 = new …; p1->f = p1; p1 = NULL;
Reference Counting Example: 1 Count: p1: f: p1 = new …; p1->f = p1; p1 = NULL;
Reference Counting Example: 2 Count: p1: f: p1 = new …; p1->f = p1; p1 = NULL;
Reference Counting Example: 1 Count: p1: f: p1 = new …; p1->f = p1; p1 = NULL;
Reference Counting Example: 1 Count: p1: Will never be deallocated f: p1 = new …; p1->f = p1; p1 = NULL;
Mark-and-Sweep Every object is given an additional single bit If the bit is set, then the object is said to be marked If the bit is not set, then the object is said to be unmarked Objects are allocated until all available memory is exhausted When this happens, the bits of all objects are cleared The registers, stack, and static data are then traversed to determine which objects are referenced When a reference to an object is found, the object becomes marked This process is recursive, in that when an object becomes marked, all of the objects to which it refers also become marked Once all accessible objects have been marked, the objects that are unmarked are deallocated
Mark-and-Sweep Mark: Mark: p1: f: g: p2: Mark: p3: Mark: p4: f: Mark:
Mark-and-Sweep Mark: Mark: p1: f: g: p2: Mark: p3: Mark: p4: f: Mark: Mark: Mark: p1: f: g: p2: Mark: p3: Mark: p4: f: Mark: f: Mark:
Mark-and-Sweep Mark: Mark: p1: f: g: p2: Mark: p3: Mark: p4: f: Mark: Mark: Mark: p1: f: g: p2: Mark: p3: Mark: p4: f: Mark: f: Mark:
Mark-and-Sweep 1 Mark: Mark: p1: f: g: p2: Mark: p3: Mark: p4: f: p1: f: g: p2: Mark: p3: Mark: p4: f: Mark: f: Mark:
Mark-and-Sweep 1 Mark: Mark: 1 p1: f: g: p2: Mark: p3: Mark: p4: f: Mark: p3: Mark: p4: f: Mark: f: Mark:
Mark-and-Sweep 1 Mark: Mark: p1: f: g: p2: Mark: p3: Mark: p4: f: p1: f: g: p2: Mark: p3: Mark: p4: f: Mark: f: Mark:
Mark-and-Sweep 1 Mark: Mark: 1 p1: f: g: p2: 1 Mark: p3: Mark: p4: f: p4: f: Mark: f: Mark:
Mark-and-Sweep 1 Mark: Mark: 1 p1: f: g: p2: 1 Mark: p3: Mark: p4: f: p4: f: Mark: f: Mark:
Mark-and-Sweep 1 Mark: Mark: 1 p1: f: g: p2: 1 Mark: p3: Mark: p4: f: p4: f: Mark: f: Mark:
Mark-and-Sweep 1 Mark: Mark: 1 p1: f: g: p2: 1 Mark: p3: Mark: p4: f: p4: f: Mark: f: Mark:
Mark-and-Sweep 1 Mark: Mark: 1 p1: f: g: p2: 1 Mark: p3: Mark: p4: f: p4: f: Mark: f: Mark:
Mark-and-Sweep 1 Mark: Mark: 1 p1: f: g: p2: 1 Mark: p3: Mark: p4: f: p4: f: Mark: f: Mark:
Mark-and-Sweep 1 Mark: Mark: 1 p1: f: g: p2: 1 Mark: p3: Mark: p4: f: p4: f: Mark: f: Mark:
Mark-and-Sweep 1 Mark: Mark: 1 p1: f: g: p2: 1 Mark: p3: Mark: 1 p4: f: Mark:
Mark-and-Sweep 1 Mark: Mark: 1 p1: f: g: p2: 1 Mark: p3: Mark: 1 p4: f: Mark:
Mark-and-Sweep 1 Mark: Mark: 1 p1: f: g: p2: 1 Mark: p3: Mark: 1 p4: f: Mark:
Mark-and-Sweep 1 Mark: Mark: 1 p1: f: g: p2: 1 Mark: p3: Mark: 1 p4: f: Mark:
Mark-and-Sweep 1 Mark: Mark: 1 p1: f: g: p2: 1 Mark: p3: Mark: 1 p4: f: Mark:
Problems with Mark-and-Sweep Often, the marking process causes a noticeable pause in execution Often, Mark-and-Sweep has to be conservative, treating fields as references, even when they are not
Reference Counting vs. Mark-and-Sweep Nonetheless, Mark-and-Sweep is generally considered the superior algorithm Consider the following program: #include <…> int main() { T *p1 = new …; T *p2 = new …; T *p3; for (int i = 0; i < 1000000000; i++) p3 = p1; p1 = p2; p2 = p3; p3 = NULL; } return 0;