Lecture5

advertisement
Virtual memory
Virtual Memory





Address spaces
VM as a tool for caching
VM as a tool for memory management
VM as a tool for memory protection
Address translation
A System Using Physical Addressing
CPU
Physical address
(PA)
4
Main memory
0:
1:
2:
3:
4:
5:
6:
7:
8:
...
M-1:
Data word

Used in “simple” systems like embedded microcontrollers in
devices like cars, elevators, and digital picture frames
A System Using Virtual Addressing
CPU Chip
CPU
Virtual address
(VA)
4100
MMU
Physical address
(PA)
4
Main memory
0:
1:
2:
3:
4:
5:
6:
7:
8:
...
M-1:
Data word


Used in all modern servers, desktops, and laptops
One of the great ideas in computer science
Address Spaces

Linear address space: Ordered set of contiguous non-negative integer
addresses:
{0, 1, 2, 3 … }

Virtual address space: Set of N = 2n virtual addresses
{0, 1, 2, 3, …, N-1}

Physical address space: Set of M = 2m physical addresses
{0, 1, 2, 3, …, M-1}

Clean distinction between data (bytes) and their attributes (addresses)
Each object can now have multiple addresses
Every byte in main memory:
one physical address, one (or more) virtual addresses


Why Virtual Memory (VM)?

Uses main memory efficiently
 Use DRAM as a cache for the parts of a virtual address space

Simplifies memory management
 Each process gets the same uniform linear address space

Isolates address spaces
 One process can’t interfere with another’s memory
 User program cannot access privileged kernel information
Virtual Memory





Address spaces
VM as a tool for caching
VM as a tool for memory management
VM as a tool for memory protection
Address translation
VM as a Tool for Caching


Virtual memory is an array of N contiguous bytes stored
on disk.
The contents of the array on disk are cached in physical
memory (DRAM cache)
 These cache blocks are called pages (size is P = 2p bytes)
Virtual memory
VP 0 Unallocated
VP 1 Cached
VP 2n-p-1
Uncached
Unallocated
Cached
Uncached
Cached
Uncached
Physical memory
0
0
Empty
PP 0
PP 1
Empty
Empty
M-1
PP 2m-p-1
N-1
Virtual pages (VPs)
stored on disk
Physical pages (PPs)
cached in DRAM
DRAM Cache Organization

DRAM cache organization driven by the enormous miss penalty
 DRAM is about 10x slower than SRAM
 Disk is about 10,000x slower than DRAM

Consequences
 Large page (block) size: typically 4-8 KB, sometimes 4 MB
 Fully associative
Any VP can be placed in any PP
 Requires a “large” mapping function – different from CPU caches
 Highly sophisticated, expensive replacement algorithms
 Too complicated and open-ended to be implemented in hardware
 Write-back rather than write-through

Page Tables

A page table is an array of page table entries (PTEs) that
maps virtual pages to physical pages.
 Per-process kernel data structure in DRAM
Physical page
number or
Valid disk address
PTE 0 0
null
1
1
0
1
0
0
PTE 7 1
null
Physical memory
(DRAM)
VP 1
VP 2
VP 7
VP 4
Virtual memory
(disk)
VP 1
Memory resident
page table
(DRAM)
VP 2
VP 3
VP 4
VP 6
VP 7
PP 0
PP 3
Page Hit

Page hit: reference to VM word that is in physical memory
(DRAM cache hit)
Virtual address
Physical page
number or
Valid disk address
PTE 0 0
null
1
1
0
1
0
0
PTE 7 1
null
Physical memory
(DRAM)
VP 1
VP 2
VP 7
VP 4
Virtual memory
(disk)
VP 1
Memory resident
page table
(DRAM)
VP 2
VP 3
VP 4
VP 6
VP 7
PP 0
PP 3
Page Fault

Page fault: reference to VM word that is not in physical
memory (DRAM cache miss)
Virtual address
Physical page
number or
Valid disk address
PTE 0 0
null
1
1
0
1
0
0
PTE 7 1
null
Physical memory
(DRAM)
VP 1
VP 2
VP 7
VP 4
Virtual memory
(disk)
VP 1
Memory resident
page table
(DRAM)
VP 2
VP 3
VP 4
VP 6
VP 7
PP 0
PP 3
Handling Page Fault

Page miss causes page fault (an exception)
Virtual address
Physical page
number or
Valid disk address
PTE 0 0
null
1
1
0
1
0
0
PTE 7 1
null
Physical memory
(DRAM)
VP 1
VP 2
VP 7
VP 4
Virtual memory
(disk)
VP 1
Memory resident
page table
(DRAM)
VP 2
VP 3
VP 4
VP 6
VP 7
PP 0
PP 3
Handling Page Fault


Page miss causes page fault (an exception)
Page fault handler selects a victim to be evicted (here VP 4)
Virtual address
Physical page
number or
Valid disk address
PTE 0 0
null
1
1
0
1
0
0
PTE 7 1
null
Physical memory
(DRAM)
VP 1
VP 2
VP 7
VP 4
Virtual memory
(disk)
VP 1
Memory resident
page table
(DRAM)
VP 2
VP 3
VP 4
VP 6
VP 7
PP 0
PP 3
Handling Page Fault


Page miss causes page fault (an exception)
Page fault handler selects a victim to be evicted (here VP 4)
Virtual address
Physical page
number or
Valid disk address
PTE 0 0
null
1
1
1
0
0
0
PTE 7 1
null
Physical memory
(DRAM)
VP 1
VP 2
VP 7
VP 3
Virtual memory
(disk)
VP 1
Memory resident
page table
(DRAM)
VP 2
VP 3
VP 4
VP 6
VP 7
PP 0
PP 3
Handling Page Fault



Page miss causes page fault (an exception)
Page fault handler selects a victim to be evicted (here VP 4)
Offending instruction is restarted: page hit!
Virtual address
Physical page
number or
Valid disk address
PTE 0 0
null
1
1
1
0
0
0
PTE 7 1
null
Physical memory
(DRAM)
VP 1
VP 2
VP 7
VP 3
Virtual memory
(disk)
VP 1
Memory resident
page table
(DRAM)
VP 2
VP 3
VP 4
VP 6
VP 7
PP 0
PP 3
Locality to the Rescue Again!

Virtual memory works because of locality

At any point in time, programs tend to access a set of active
virtual pages called the working set
 Programs with better temporal locality will have smaller working sets

If (working set size < main memory size)
 Good performance for one process after compulsory misses

If ( SUM(working set sizes) > main memory size )
 Thrashing: Performance meltdown where pages are swapped (copied)
in and out continuously
Virtual Memory





Address spaces
VM as a tool for caching
VM as a tool for memory management
VM as a tool for memory protection
Address translation
VM as a Tool for Memory Management

Key idea: each process has its own virtual address space
 It can view memory as a simple linear array
 Mapping function scatters addresses through physical memory

Well chosen mappings simplify memory allocation and management
Virtual
Address
Space for
Process 1:
0
VP 1
VP 2
Address
translation
0
PP 2
...
Physical
Address
Space
(DRAM)
N-1
PP 6
Virtual
Address
Space for
Process 2:
0
PP 8
VP 1
VP 2
...
...
N-1
M-1
(e.g., read-only
library code)
VM as a Tool for Memory Management

Memory allocation
 Each virtual page can be mapped to any physical page
 A virtual page can be stored in different physical pages at different times

Sharing code and data among processes
 Map virtual pages to the same physical page (here: PP 6)
Virtual
Address
Space for
Process 1:
0
VP 1
VP 2
Address
translation
0
PP 2
...
Physical
Address
Space
(DRAM)
N-1
PP 6
Virtual
Address
Space for
Process 2:
0
PP 8
VP 1
VP 2
...
...
N-1
M-1
(e.g., read-only
library code)
Simplifying Linking and Loading
Kernel virtual memory

Linking
0xc0000000
 Each program has similar virtual
User stack
(created at runtime)
address space
 Code, stack, and shared libraries
always start at the same address
Memory
invisible to
user code
%esp
(stack
pointer)
Memory-mapped region for
shared libraries
0x40000000

Loading
 execve() allocates virtual pages
brk
Run-time heap
(created by malloc)
for .text and .data sections
= creates PTEs marked as invalid
 The .text and .data sections
are copied, page by page, on
demand by the virtual memory
system
Read/write segment
(.data, .bss)
Read-only segment
(.init, .text, .rodata)
0x08048000
0
Unused
Loaded
from
the
executable
file
Virtual Memory





Address spaces
VM as a tool for caching
VM as a tool for memory management
VM as a tool for memory protection
Address translation
VM as a Tool for Memory Protection


Extend PTEs with permission bits
Page fault handler checks these before remapping
 If violated, send process SIGSEGV (segmentation fault)
SUP
Process i:
READ WRITE
Address
VP 0:
No
Yes
No
PP 6
VP 1:
No
Yes
Yes
PP 4
VP 2:
Yes
Yes
Yes
•
•
•
PP 2
Physical
Address Space
PP 2
PP 4
PP 6
SUP
Process j:
READ WRITE
Address
VP 0:
No
Yes
No
PP 9
VP 1:
Yes
Yes
Yes
PP 6
VP 2:
No
Yes
Yes
PP 11
PP 8
PP 9
PP 11
Virtual Memory





Address spaces
VM as a tool for caching
VM as a tool for memory management
VM as a tool for memory protection
Address translation
VM Address Translation

Virtual Address Space
 V = {0, 1, …, N–1}

Physical Address Space
 P = {0, 1, …, M–1}

Address Translation
 MAP: V  P U {}
 For virtual address a:


MAP(a) = a’ if data at virtual address a is at physical address a’ in P
MAP(a) =  if data at virtual address a is not in physical memory
– Either invalid or stored on disk
Summary of Address Translation Symbols



Basic Parameters
 N = 2n : Number of addresses in virtual address space
 M = 2m : Number of addresses in physical address space
 P = 2p : Page size (bytes)
Components of the virtual address (VA)
 TLBI: TLB index
 TLBT: TLB tag
 VPO: Virtual page offset
 VPN: Virtual page number
Components of the physical address (PA)
 PPO: Physical page offset (same as VPO)
 PPN: Physical page number
 CO: Byte offset within cache line
 CI: Cache index
 CT: Cache tag
Address Translation With a Page Table
Virtual address
n-1
Page table
base register
(PTBR)
Page table address
for process
p p-1
Virtual page number (VPN)
0
Virtual page offset (VPO)
Page table
Valid
Physical page number (PPN)
Valid bit = 0:
page not in memory
(page fault)
m-1
Physical page number (PPN)
Physical address
p p-1
Physical page offset (PPO)
0
Address Translation: Page Hit
2
PTEA
CPU Chip
CPU
1
VA
PTE
MMU
3
PA
4
Data
5
1) Processor sends virtual address to MMU
2-3) MMU fetches PTE from page table in memory
4) MMU sends physical address to cache/memory
5) Cache/memory sends data word to processor
Cache/
Memory
Address Translation: Page Fault
Exception
Page fault handler
4
2
PTEA
CPU Chip
CPU
1
VA
7
MMU
PTE
3
Victim page
5
Cache/
Memory
Disk
New page
6
1) Processor sends virtual address to MMU
2-3) MMU fetches PTE from page table in memory
4) Valid bit is zero, so MMU triggers page fault exception
5) Handler identifies victim (and, if dirty, pages it out to disk)
6) Handler pages in new page and updates PTE in memory
7) Handler returns to original process, restarting faulting instruction
Integrating VM and Cache
PTE
CPU Chip
PTEA
CPU
PTE
PTEA
hit
VA
MMU
PTEA
miss
PA
PA
miss
PA
Memory
Data
PA
hit
Data
PTEA
L1
cache
VA: virtual address, PA: physical address, PTE: page table entry, PTEA = PTE address
Speeding up Translation with a TLB

Page table entries (PTEs) are cached in L1 like any other
memory word
 PTEs may be evicted by other data references

Solution: Translation Lookaside Buffer (TLB)
 Small hardware cache in MMU
 Maps virtual page numbers to physical page numbers
 Contains complete page table entries for small number of pages
TLB Hit
CPU Chip
CPU
TLB
2
PTE
VPN
3
1
VA
MMU
Data
5
A TLB hit eliminates a memory access
PA
4
Cache/
Memory
TLB Miss
CPU Chip
TLB
2
4
PTE
VPN
CPU
1
VA
MMU
3
PTEA
PA
Cache/
Memory
5
Data
6
A TLB miss incurs an additional memory access (the PTE)
Fortunately, TLB misses are rare. Why?
Multi-Level Page Tables

Suppose:
 4KB (212) page size, 48-bit address space, 8-byte PTE

Problem:
 Would need a 512 GB page table!

Level 2
Tables
Level 1
Table
248 * 2-12 * 23 = 239 bytes
...

Common solution:
 Multi-level page tables
 Example: 2-level page table


Level 1 table: each PTE points to a page table (always
memory resident)
Level 2 table: each PTE points to a page
(paged in and out like any other data)
...
A Two-Level Page Table Hierarchy
Level 1
page table
Level 2
page tables
Virtual
memory
VP 0
PTE 0
PTE 0
...
PTE 1
...
VP 1023
PTE 2 (null)
PTE 1023
VP 1024
0
2K allocated VM pages
for code and data
...
PTE 3 (null)
VP 2047
PTE 4 (null)
PTE 0
PTE 5 (null)
...
PTE 6 (null)
PTE 1023
Gap
PTE 7 (null)
6K unallocated VM pages
PTE 8
(1K - 9)
null PTEs
1023 null
PTEs
PTE 1023
...
32 bit addresses, 4KB pages, 4-byte PTEs
1023
unallocated
pages
VP 9215
1023 unallocated pages
1 allocated VM page
for the stack
Summary

Programmer’s view of virtual memory
 Each process has its own private linear address space
 Cannot be corrupted by other processes

System view of virtual memory
 Uses memory efficiently by caching virtual memory pages
Efficient only because of locality
 Simplifies memory management and programming
 Simplifies protection by providing a convenient interpositioning point
to check permissions

Simple Memory System Example

Addressing
 14-bit virtual addresses
 12-bit physical address
 Page size = 64 bytes
13
12
11
10
9
8
7
6
5
4
3
2
1
VPN
VPO
Virtual Page Number
Virtual Page Offset
11
10
9
8
7
6
5
4
3
2
1
PPN
PPO
Physical Page Number
Physical Page Offset
0
0
Simple Memory System Page Table
Only show first 16 entries (out of 256)
VPN
PPN
Valid
VPN
PPN
Valid
00
28
1
08
13
1
01
–
0
09
17
1
02
33
1
0A
09
1
03
02
1
0B
–
0
04
–
0
0C
–
0
05
16
1
0D
2D
1
06
–
0
0E
11
1
07
–
0
0F
0D
1
Simple Memory System TLB


16 entries
4-way associative
TLBT
13
12
11
10
TLBI
9
8
7
6
5
4
3
2
1
0
VPO
VPN
Set
Tag
PPN
Valid
Tag
PPN
Valid
Tag
PPN
Valid
Tag
PPN
Valid
0
03
–
0
09
0D
1
00
–
0
07
02
1
1
03
2D
1
02
–
0
04
–
0
0A
–
0
2
02
–
0
08
–
0
06
–
0
03
–
0
3
07
–
0
03
0D
1
0A
34
1
02
–
0
Simple Memory System Cache



16 lines, 4-byte block size
Physically addressed
Direct mapped
CT
11
10
9
CI
8
7
6
5
4
CO
3
PPN
2
1
0
PPO
Idx
Tag
Valid
B0
B1
B2
B3
Idx
Tag
Valid
B0
B1
B2
B3
0
19
1
99
11
23
11
8
24
1
3A
00
51
89
1
15
0
–
–
–
–
9
2D
0
–
–
–
–
2
1B
1
00
02
04
08
A
2D
1
93
15
DA
3B
3
36
0
–
–
–
–
B
0B
0
–
–
–
–
4
32
1
43
6D
8F
09
C
12
0
–
–
–
–
5
0D
1
36
72
F0
1D
D
16
1
04
96
34
15
6
31
0
–
–
–
–
E
13
1
83
77
1B
D3
7
16
1
11
C2
DF
03
F
14
0
–
–
–
–
Address Translation Example #1
Virtual Address: 0x03D4
TLBT
TLBI
13
12
11
10
9
8
7
6
5
4
3
2
1
0
0
0
0
0
1
1
1
1
0
1
0
1
0
0
VPN
VPN 0x0F
___
0x3
TLBI ___
VPO
0x03
TLBT ____
Y
TLB Hit? __
N
Page Fault? __
PPN: 0x0D
____
Physical Address
CI
CT
11
10
9
8
7
6
5
4
3
2
1
0
0
0
1
1
0
1
0
1
0
1
0
0
PPN
0
CO ___
CO
0x5
CI___
0x0D
CT ____
PPO
Y
Hit? __
0x36
Byte: ____
Address Translation Example #2
Virtual Address: 0x0B8F
TLBT
TLBI
13
12
11
10
9
8
7
6
5
4
3
2
1
0
0
0
1
0
1
1
1
0
0
0
1
1
1
1
VPN
VPN 0x2E
___
2
TLBI ___
VPO
0x0B
TLBT ____
N
TLB Hit? __
Y
Page Fault? __
TBD
PPN: ____
Physical Address
CI
CT
11
10
9
8
7
6
PPN
CO ___
CI___
CT ____
5
4
CO
3
PPO
Hit? __
Byte: ____
2
1
0
Address Translation Example #3
Virtual Address: 0x0020
TLBT
TLBI
13
12
11
10
9
8
7
6
5
4
3
2
1
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
VPN
VPN 0x00
___
0
TLBI ___
VPO
0x00
TLBT ____
N
TLB Hit? __
N
Page Fault? __
PPN: 0x28
____
Physical Address
CI
CT
11
10
9
8
7
6
5
4
3
2
1
0
1
0
1
0
0
0
1
0
0
0
0
0
PPN
0
CO___
CO
0x8
CI___
0x28
CT ____
PPO
N
Hit? __
Mem
Byte: ____
Dynamic Memory Allocation
Dynamic Memory Allocation

Application
Programmers use
dynamic memory
allocators (such as
malloc) to acquire VM
at run time.
Dynamic Memory Allocator
Heap
 For data structures whose
User stack
size is only known at
runtime.

Dynamic memory
allocators manage an
area of process virtual
memory known as the
heap.
Heap (via malloc)
Uninitialized data (.bss)
Initialized data (.data)
Program text (.text)
0
Top of heap
(brk ptr)
Dynamic Memory Allocation


Allocator maintains heap as collection of variable sized
blocks, which are either allocated or free
Types of allocators
 Explicit allocator: application allocates and frees space
E.g., malloc and free in C
 Implicit allocator: application allocates, but does not free space
 E.g. garbage collection in Java, ML, and Lisp


Will discuss simple explicit memory allocation today
The malloc Package
#include <stdlib.h>
void *malloc(size_t size)
 Successful:
 Returns a pointer to a memory block of at least size bytes
(typically) aligned to 8-byte boundary
 If size == 0, returns NULL
 Unsuccessful: returns NULL (0) and sets errno
void free(void *p)
 Returns the block pointed at by p to pool of available memory
 p must come from a previous call to malloc or realloc
Other functions
 calloc: Version of malloc that initializes allocated block to zero.
 realloc: Changes the size of a previously allocated block.
 sbrk: Used internally by allocators to grow or shrink the heap
malloc Example
void foo(int n) {
int i, *p;
/* Allocate a block of n ints */
p = (int *) malloc(n * sizeof(int));
if (p == NULL) {
perror("malloc");
exit(0);
}
/* Initialize allocated block */
for (i=0; i<n; i++)
p[i] = i;
/* Return p to the heap */
free(p);
}
Allocation Example
p1 = malloc(4)
p2 = malloc(5)
p3 = malloc(6)
free(p2)
p4 = malloc(2)
Constraints

Applications
 Can issue arbitrary sequence of malloc and free requests
 free request must be to a malloc’d block

Allocators
 Can’t control number or size of allocated blocks
 Must respond immediately to malloc requests
i.e., can’t reorder or buffer requests
Must allocate blocks from free memory
 i.e., can only place allocated blocks in free memory
Must align blocks so they satisfy all alignment requirements
 8 byte alignment for GNU malloc (libc malloc) on Linux boxes
Can manipulate and modify only free memory
Can’t move the allocated blocks once they are malloc’d
 i.e., compaction is not allowed





Performance Goal: Throughput

Given some sequence of malloc and free requests:
 R0, R1, ..., Rk, ... , Rn-1

Goals: maximize throughput and peak memory utilization
 These goals are often conflicting

Throughput:
 Number of completed requests per unit time
 Example:


5,000 malloc calls and 5,000 free calls in 10 seconds
Throughput is 1,000 operations/second
Performance Goal: Peak Memory Utilization

Given some sequence of malloc and free requests:
 R0, R1, ..., Rk, ... , Rn-1

Def: Aggregate payload Pk
 malloc(p) results in a block with a payload of p bytes
 After request Rk has completed, the aggregate payload Pk is the sum of
currently allocated payloads

Def: Current heap size Hk
 Assume Hk is monotonically nondecreasing


i.e., heap only grows when allocator uses sbrk
Def: Peak memory utilization after k requests
 Uk = ( maxi<k Pi ) / Hk
Fragmentation

Poor memory utilization caused by fragmentation
 internal fragmentation
 external fragmentation
Internal Fragmentation

For a given block, internal fragmentation occurs if payload is
smaller than block size
Block
Internal
fragmentation

Payload
Caused by
 Overhead of maintaining heap data structures
 Padding for alignment purposes
 Explicit policy decisions
(e.g., to return a big block to satisfy a small request)

Depends only on the pattern of previous requests
 Thus, easy to measure
Internal
fragmentation
External Fragmentation

Occurs when there is enough aggregate heap memory,
but no single free block is large enough
p1 = malloc(4)
p2 = malloc(5)
p3 = malloc(6)
free(p2)
p4 = malloc(6)

Oops! (what would happen now?)
Depends on the pattern of future requests
 Thus, difficult to measure
Implementation Issues

How do we know how much memory to free given just a
pointer?

How do we keep track of the free blocks?

What do we do with the extra space when allocating a
structure that is smaller than the free block it is placed in?

How do we pick a block to use for allocation -- many
might fit?

How do we reinsert freed block?
Knowing How Much to Free

Standard method
 Keep the length of a block in the word preceding the block.
This word is often called the header field or header
 Requires an extra word for every allocated block

p0
p0 = malloc(4)
5
block size
free(p0)
data
Keeping Track of Free Blocks

Method 1: Implicit list using length—links all blocks
5

6
2
Method 2: Explicit list among the free blocks using pointers
5

4
4
6
2
Method 3: Segregated free list
 Different free lists for different size classes

Method 4: Blocks sorted by size
 Can use a balanced tree (e.g. Red-Black tree) with pointers within each
free block, and the length used as a key
Method 1: Implicit List

For each block we need both size and allocation status
 Could store this information in two words: wasteful!

Standard trick
 If blocks are aligned, some low-order address bits are always 0
 Instead of storing an always-0 bit, use it as a allocated/free flag
 When reading size word, must mask out this bit
1 word
Size
Format of
allocated and
free blocks
Payload
a
a = 1: Allocated block
a = 0: Free block
Size: block size
Payload: application data
(allocated blocks only)
Optional
padding
Detailed Implicit Free List Example
Start
of
heap
Unused
8/0
16/1
Double-word
aligned
32/0
16/1
0/1
Allocated blocks: shaded
Free blocks: unshaded
Headers: labeled with size in bytes/allocated bit
Implicit List: Finding a Free Block

First fit:
 Search list from beginning, choose first free block that fits:
p = start;
while ((p < end) &&
((*p & 1) ||
(*p <= len)))
p = p + (*p & -2);
\\
\\
\\
\\
not passed end
already allocated
too small
goto next block (word addressed)
 Can take linear time in total number of blocks (allocated and free)
 In practice it can cause “splinters” at beginning of list

Next fit:
 Like first fit, but search list starting where previous search finished
 Should often be faster than first fit: avoids re-scanning unhelpful blocks
 Some research suggests that fragmentation is worse

Best fit:
 Search the list, choose the best free block: fits, with fewest bytes left over
 Keeps fragments small—usually helps fragmentation
 Will typically run slower than first fit
Implicit List: Allocating in Free Block

Allocating in a free block: splitting
 Since allocated space might be smaller than free space, we might want
to split the block
4
4
6
2
p
addblock(p, 4)
4
4
4
void addblock(ptr p, int len) {
int newsize = ((len + 1) >> 1) << 1;
int oldsize = *p & -2;
*p = newsize | 1;
if (newsize < oldsize)
*(p+newsize) = oldsize - newsize;
}
2
2
// round up to even
// mask out low bit
// set new length
// set length in remaining
//
part of block
Implicit List: Freeing a Block

Simplest implementation:
 Need only clear the “allocated” flag
void free_block(ptr p) { *p = *p & -2 }
 But can lead to “false fragmentation”
4
4
2
2
2
2
p
free(p)
4
malloc(5)
4
4
4
Oops!
There is enough free space, but the allocator won’t be able to find it
Implicit List: Coalescing

Join (coalesce) with next/previous blocks, if they are free
 Coalescing with next block
4
4
4
2
2
2
2
p
free(p)
4
4
void free_block(ptr p) {
*p = *p & -2;
next = p + *p;
if ((*next & 1) == 0)
*p = *p + *next;
}
6
// clear allocated flag
// find next block
// add to this block if
//
not allocated
 But how do we coalesce with previous block?
logically
gone
Implicit List: Bidirectional Coalescing

Boundary tags [Knuth73]
 Replicate size/allocated word at “bottom” (end) of free blocks
 Allows us to traverse the “list” backwards, but requires extra space
 Important and general technique!
4
4 4
Header
Format of
allocated and
free blocks
Boundary tag
(footer)
4 6
Size
6 4
a
a = 1: Allocated block
a = 0: Free block
Size: Total block size
Payload and
padding
Size
4
Payload: Application data
(allocated blocks only)
a
Constant Time Coalescing
Block being
freed
Case 1
Case 2
Case 3
Case 4
Allocated
Allocated
Free
Free
Allocated
Free
Allocated
Free
Constant Time Coalescing (Case 1)
m1
1
m1
1
m1
1
m1
1
n
1
n
0
n
1
n
0
m2
1
m2
1
m2
1
m2
1
Constant Time Coalescing (Case 2)
m1
1
m1
1
m1
1
m1
1
n
1
n+m2
0
n
1
m2
0
m2
0
n+m2
0
Constant Time Coalescing (Case 3)
m1
0
n+m1
0
m1
0
n
1
n
1
n+m1
0
m2
1
m2
1
m2
1
m2
1
Constant Time Coalescing (Case 4)
m1
0
m1
0
n
1
n
1
m2
0
m2
0
n+m1+m2
0
n+m1+m2
0
Disadvantages of Boundary Tags

Internal fragmentation

Can it be optimized?
 Which blocks need the footer tag?
 What does that mean?
Summary of Key Allocator Policies

Placement policy:
 First-fit, next-fit, best-fit, etc.
 Trades off lower throughput for less fragmentation
 Interesting observation: segregated free lists (next lecture)
approximate a best fit placement policy without having to search
entire free list

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 each time free is called
 Deferred coalescing: try to improve performance of free by deferring
coalescing until needed. Examples:
 Coalesce as you scan the free list for malloc
 Coalesce when the amount of external fragmentation reaches
some threshold
Implicit Lists: Summary


Implementation: very simple
Allocate cost:
 linear time worst case

Free cost:
 constant time worst case
 even with coalescing

Memory usage:
 will depend on placement policy
 First-fit, next-fit or best-fit

Not used in practice for malloc/free because of lineartime allocation
 used in many special purpose applications

However, the concepts of splitting and boundary tag
coalescing are general to all allocators
Dynamic memory allocation



Explicit free lists
Segregated free lists
Garbage collection
Keeping Track of Free Blocks

Method 1: Implicit free list using length—links all blocks
5

6
2
Method 2: Explicit free list among the free blocks using pointers
5

4
4
6
2
Method 3: Segregated free list
 Different free lists for different size classes

Method 4: Blocks sorted by size
 Can use a balanced tree (e.g. Red-Black tree) with pointers within each
free block, and the length used as a key
Explicit Free Lists
Allocated (as before)
Size
a
Free
Size
a
Next
Prev
Payload and
padding
Size

a
Size
a
Maintain list(s) of free blocks, not all blocks
 The “next” free block could be anywhere
So we need to store forward/back pointers, not just sizes
 Still need boundary tags for coalescing
 Luckily we track only free blocks, so we can use payload area

Explicit Free Lists

Logically:
A

B
C
Physically: blocks can be in any order
Forward (next) links
A
4
B
4 4
4 6
6 4
C
4 4
4
Back (prev) links
Allocating From Explicit Free Lists
conceptual graphic
Before
After
(with splitting)
= malloc(…)
Freeing With Explicit Free Lists

Insertion policy: Where in the free list do you put a newly
freed block?
 LIFO (last-in-first-out) policy

Insert freed block at the beginning of the free list

Pro: simple and constant time

Con: studies suggest fragmentation is worse than address ordered
 Address-ordered policy

Insert freed blocks so that free list blocks are always in address
order:
addr(prev) < addr(curr) < addr(next)

Con: requires search

Pro: studies suggest fragmentation is lower than LIFO
Freeing With a LIFO Policy (Case 1)
conceptual graphic
Before
free( )
Root

Insert the freed block at the root of the list
After
Root
Freeing With a LIFO Policy (Case 2)
conceptual graphic
Before
free( )
Root

Splice out predecessor block, coalesce both memory blocks,
and insert the new block at the root of the list
After
Root
Freeing With a LIFO Policy (Case 3)
conceptual graphic
Before
free( )
Root

Splice out successor block, coalesce both memory blocks and
insert the new block at the root of the list
After
Root
Freeing With a LIFO Policy (Case 4)
conceptual graphic
Before
free( )
Root

Splice out predecessor and successor blocks, coalesce all 3
memory blocks and insert the new block at the root of the list
After
Root
Explicit List Summary

Comparison to implicit list:
 Allocate is linear time in number of free blocks instead of all blocks
Much faster when most of the memory is full
 Slightly more complicated allocate and free since needs to splice blocks
in and out of the list
 Some extra space for the links (2 extra words needed for each block)
 Does this increase internal fragmentation?


Most common use of linked lists is in conjunction with
segregated free lists
 Keep multiple linked lists of different size classes, or possibly for
different types of objects
Keeping Track of Free Blocks

Method 1: Implicit list using length—links all blocks
5

6
2
Method 2: Explicit list among the free blocks using pointers
5

4
4
6
2
Method 3: Segregated free list
 Different free lists for different size classes

Method 4: Blocks sorted by size
 Can use a balanced tree (e.g. Red-Black tree) with pointers within each
free block, and the length used as a key
Dynamic memory allocators



Explicit free lists
Segregated free lists
Garbage collection
Segregated List (Seglist) Allocators

Each size class of blocks has its own free list
1-2
3
4
5-8
9-inf


Often have separate classes for each small size
For larger sizes: One class for each two-power size
Seglist Allocator

Given an array of free lists, each one for some size class

To allocate a block of size n:
 Search appropriate free list for block of size m > n
 If an appropriate block is found:
Split block and place fragment on appropriate list (optional)
 If no block is found, try next larger class
 Repeat until block is found


If no block is found:
 Request additional heap memory from OS (using sbrk())
 Allocate block of n bytes from this new memory
 Place remainder as a single free block in largest size class.
Seglist Allocator (cont.)

To free a block:
 Coalesce and place on appropriate list (optional)

Advantages of seglist allocators
 Higher throughput
log time for power-of-two size classes
 Better memory utilization
 First-fit search of segregated free list approximates a best-fit
search of entire heap.


Extreme case: Giving each block its own size class is equivalent to
best-fit.
More Info on Allocators

D. Knuth, “The Art of Computer Programming”, 2nd edition,
Addison Wesley, 1973
 The classic reference on dynamic storage allocation

Wilson et al, “Dynamic Storage Allocation: A Survey and
Critical Review”, Proc. 1995 Int’l Workshop on Memory
Management, Kinross, Scotland, Sept, 1995.
 Comprehensive survey
Dynamic memory allocators



Explicit free lists
Segregated free lists
Garbage collection
Implicit Memory Management:
Garbage Collection

Garbage collection: automatic reclamation of heap-allocated
storage—application never has to free
void foo() {
int *p = malloc(128);
return; /* p block is now garbage */
}

Common in functional languages, scripting languages, and
modern object oriented languages:
 Lisp, ML, Java, Python, Mathematica

Variants (“conservative” garbage collectors) exist for C and C++
 However, cannot necessarily collect all garbage
Garbage Collection

How does the memory manager know when memory can be
freed?
 In general we cannot know what is going to be used in the future since it
depends on conditionals
 But we can tell that certain blocks cannot be used if there are no
pointers to them

Must make certain assumptions about pointers
 Memory manager can distinguish pointers from non-pointers
 All pointers point to the start of a block
 Cannot hide pointers
(e.g., by coercing them to an int, and then back again)
Classical GC Algorithms

Mark-and-sweep collection (McCarthy, 1960)
 Does not move blocks (unless you also “compact”)

Reference counting (Collins, 1960)
 Does not move blocks (not discussed)

Copying collection (Minsky, 1963)
 Moves blocks (not discussed)

Generational Collectors (Lieberman and Hewitt, 1983)
 Collection based on lifetimes


Most allocations become garbage very soon

So focus reclamation work on zones of memory recently allocated
For more information:
Jones and Lin, “Garbage Collection: Algorithms for Automatic
Dynamic Memory”, John Wiley & Sons, 1996.
Memory as a Graph

We view memory as a directed graph
 Each block is a node in the graph
 Each pointer is an edge in the graph
 Locations not in the heap that contain pointers into the heap are called
root nodes (e.g. registers, locations on the stack, global variables)
Root nodes
Heap nodes
reachable
Not-reachable
(garbage)
A node (block) is reachable if there is a path from any root to that node.
Non-reachable nodes are garbage (cannot be needed by the application)
Mark and Sweep Collecting

Can build on top of malloc/free package
 Allocate using malloc until you “run out of space”

When out of space:
 Use extra mark bit in the head of each block
 Mark: Start at roots and set mark bit on each reachable block
 Sweep: Scan all blocks and free blocks that are not marked
root
Note: arrows
here denote
memory refs, not
free list ptrs.
Before mark
After mark
After sweep
Mark bit set
free
free
Download