Download presentation
1
Dynamic Memory Allocation
2
Implementation of a simple allocator Explicit Free List
Outline Implementation of a simple allocator Explicit Free List Segregated Free List Suggested reading: 10.9, 10.10, 10.11, 10.12, 10.13 Segregate:隔离
3
Dynamic Memory Allocation P731
Explicit vs. Implicit Memory Allocator Explicit: application allocates and frees space E.g., malloc and free in C Implicit: application allocates, but does not free space E.g. garbage collection in Java, ML or Lisp
4
Dynamic Memory Allocation
In both cases the memory allocator provides an abstraction of memory as a set of blocks Doles out free memory blocks to application Doles: 发放
5
10.9.1 The malloc and free Functions
6
Malloc package P731 #include <stdlib.h>
void *malloc(size_t size) if successful: returns a pointer to a memory block of at least size bytes, aligned to 8-byte boundary. if size==0, returns NULL if unsuccessful: returns NULL 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,calloc or realloc.
7
sbrk() Function P732 #include <unistd.h> void *sbrk(int incr)
If successful It returns the old value of brk If unsuccessful It returns –1 It sets errno to ENOMEM If incr is zero It returns the current value incr can be a negative number
8
Assumptions made in this lecture
memory is word addressed (each word can hold a pointer) Allocated block (4 words) Free block (3 words) Free word Allocated word
9
Allocation examples Figure 10.36 P733 p1 = malloc(4) p2 = malloc(5)
free(p2) p4 = malloc(2) Figure P733
10
10.9.2 Why Dynamic Memory Allocation
11
Why Dynamic Memory Allocation P734
1 #include "csapp.h" 2 #define MAXN 15213 3 4 int array[MAXN]; 5 6 int main() 7 { 8 int i, n; 9 10 scanf("%d", &n); 11 if (n > MAXN) 12 app_error("Input file too big"); 13 for (i = 0; i < n; i++) 14 scanf("%d", &array[i]); 15 exit(0); 16 }
12
Why Dynamic Memory Allocation P734
1 #include "csapp.h" 2 3 int main() 4 { 5 int *array, i, n; 6 7 scanf("%d", &n); 8 array = (int *)Malloc(n * sizeof(int)); 9 for (i = 0; i < n; i++) 10 scanf("%d", &array[i]); 11 exit(0); 12 }
13
10.9.3 Allocator Requirements and Goals
14
Constraints Applications:
Can issue arbitrary sequence of allocation and free requests Free requests must correspond to an allocated block
15
Constraints Allocators
Can’t control number or size of allocated blocks Must respond immediately to all allocation 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
16
Constraints Allocators
Must align blocks so they satisfy all alignment requirements usually 8 byte alignment Can only manipulate and modify free memory Can’t move the allocated blocks once they are allocated i.e., compaction is not allowed
17
Given some sequence of malloc and free requests:
Goals P735 Given some sequence of malloc and free requests: R0, R1, ..., Rk, ... , Rn-1 Want to maximize throughput and peak memory utilization. These goals are often conflicting
18
Performance goals: throughput
Number of completed requests per unit time Example: 5,00 malloc calls and 5,00 free calls in 1 seconds throughput is 1,000 operations/second.
19
Performance goals: 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. Aggregate: 合计,累计
20
Performance goals: peak memory utilization
Given some sequence of malloc and free requests: R0, R1, ..., Rk, ... , Rn-1 Def: current heap size is denoted by Hk Note that Hk is monotonically nondecreasing Def: peak memory utilization: After k requests, peak memory utilization is: Uk = ( maxi<k Pi ) / Hk
21
Fragmentation Fragmentation: 分成碎片
22
Poor memory utilization caused by fragmentation
Comes in two forms: internal fragmentation external fragmentation
23
Internal Fragmentation
For some block, internal fragmentation is the difference between the block size and the payload size payload Internal fragmentation block
24
Internal Fragmentation
Is caused by overhead of maintaining heap data structures, padding for alignment purposes, or explicit policy decisions (e.g., not to split the block). Depends only on the pattern of previous requests, and thus is easy to measure.
25
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)
26
External fragmentation
External fragmentation depends on the pattern of future requests and thus is difficult to measure
27
10.9.5 Implementation Issues
28
Implementation issues
How do we know how much memory to free just given a pointer? How do we keep track of the free blocks? p1 = malloc(1) p0 free(p0)
29
Implementation issues
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? Reinsert:重新插入
30
Knowing how much to free
Standard method keep the length of a structure in the word preceding the structure This word is often called the header field or header requires an extra word for every allocated structure
31
Knowing how much to free
free(p0) p0 = malloc(4) p0 Block size data 5
32
Implicit Free Lists Implicit:暗示的,绝对的
33
Need to identify whether each block is free or allocated
Implicit list Need to identify whether each block is free or allocated Can use extra bit Bit can be put in the same word as the size if block sizes are always multiples of 8 (mask out low order bit when reading size).
34
Implicit list Figure 10.37 P738 Figure 10.38 P738 size 1 word
Format of allocated and free blocks payload a = 1: allocated block a = 0: free block size: block size payload: application data (allocated blocks only) a optional padding Figure P738 4 2 6 p Figure P738
35
10.9.7 Placing Allocated Blocks
36
Finding a free block 1)First fit:
Search list from beginning, choose first free block that fits Can take linear time in total number of blocks (allocated and free) In practice it can cause “splinters” at beginning of list p = start; while ((p < end) || \\ not passed end (*p & 1) || \\ already allocated (*p <= len) ); \\ too small
37
Finding a free block 2) Next fit: 3) Best fit:
Like first-fit, but search list from location of end of previous search Research suggests that fragmentation is worse 3) Best fit: Search the list, choose the free block with the closest size that fits Keeps fragments small --- usually helps fragmentation Will typically run slower than first-fit
38
Splitting Free Blocks
39
Allocating in a 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 2 6 p 4 2 Figure P740
40
10.9.9 Getting Additional Heap Memory
41
10.9.10 Coalescing Free Blocks
42
Simplest implementation:
Freeing a block Simplest implementation: Only need to clear allocated flag But can lead to “false fragmentation” There is enough free space, but the allocator won’t be able to find it 4 2 free(p) p malloc(5)
43
Join with next and/or previous block if they are free
Coalescing Join with next and/or previous block if they are free Coalescing with next block But how do we coalesce with previous block? 4 2 free(p) p 6 Figure P741
44
10.9.11 Coalescing with Boundary Tags
45
Bidirectional 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!
46
Bidirectional Figure 10.41 P742 size 1 word Format of allocated and
free blocks payload and padding a = 1: allocated block a = 0: free block size: block size payload: application data (allocated blocks only) a boundary tag (footer) header Figure P742 4 6
47
Constant time coalescing
allocated free block being freed Case 1 Case 2 Case 3 Case 4 Figure P743
48
Constant time coalescing (case 1)
n 1 n m2 1 m2 1 m2 1 m2 1
49
Constant time coalescing (case 2)
1 m1 1 m1 1 m1 1 n 1 n+m2 n 1 m2 m2 n+m2
50
Constant time coalescing (case 3)
n+m1 m1 n 1 n 1 n+m1 m2 1 m2 1 m2 1 m2 1
51
Constant time coalescing (case 4)
n+m1+m2 m1 n 1 n 1 m2 m2 n+m1+m2
52
10.9.12 Putting it Together: Implementing a Simple Allocator
53
Implementing a Simple Allocator
1 int mm_init(void); 2 void *mm_malloc(size_t size); 3 void mm_free(void *bp);
54
Data Structure Figure P745
55
Initialize Figure 10.43 P745 1 #include "csapp.h" 2
3 /* private global variables */ 4 static void *mem_start_brk; /* points to first byte of the heap */ 5 static void *mem_brk; /* points to last byte of the heap */ 6 static void *mem_max_addr; /* max virtual address for the heap */ 7 8 /* 9 * mem_init - initializes the memory system model 10 */ 11 void mem_init(int size) 12 { 13 mem_start_brk = (void *)Malloc(size); /* models available VM */ 14 mem_brk = mem_start_brk; /* heap is initially empty */ 15 mem_max_addr = mem_start_brk + size; /* max VM address for heap */ 16 } 17
56
Initialize 18 /* 19 * mem_sbrk - simple model of the the sbrk function. Extends the heap 20 * by incr bytes and returns the start address of the new area. In 21 * this model, the heap cannot be shrunk. 22 */ 23 void *mem_sbrk(int incr) 24 { 25 void *old_brk = mem_brk; 26 27 if ( (incr < 0) || ((mem_brk + incr) > mem_max_addr)) { 28 errno = ENOMEM; 29 return (void *)-1; 30 } 31 mem_brk += incr; 32 return old_brk; 33 }
57
Macros Figure 10.45 P746 1 /* Basic constants and macros */
2 #define WSIZE 4 /* word size (bytes) */ 3 #define DSIZE 8 /* doubleword size (bytes) */ 4 #define CHUNKSIZE (1<<12) /* initial heap size (bytes) */ 5 #define OVERHEAD 8 /* overhead of header and footer (bytes) */ 6 7 #define MAX(x, y) ((x) > (y)? (x) : (y)) 8 9 /* Pack a size and allocated bit into a word */ 10 #define PACK(size, alloc) ((size) | (alloc)) 11 12 /* Read and write a word at address p */ 13 #define GET(p) (*(size_t *)(p)) 14 #define PUT(p, val) (*(size_t *)(p) = (val)) 15
58
Macros Size_ t size = GET SIZE(HDRP(NEXT_BLKP(bp)));
16 /* Read the size and allocated fields from address p */ 17 #define GET_SIZE(p) (GET(p) & ˜0x7) 18 #define GET_ALLOC(p) (GET(p) & 0x1) 19 20 /* Given block ptr bp, compute address of its header and footer */ 21 #define HDRP(bp) ((void *)(bp) - WSIZE) 22 #define FTRP(bp) ((void *)(bp) + GET_SIZE(HDRP(bp)) - DSIZE) 23 24 /* Given block ptr bp, compute address of next and previous blocks */ 25 #define NEXT_BLKP(bp) ((void *)(bp) + GET_SIZE(HDRP(bp))) #define PREV_BLKP(bp) ((void *)(bp) - GET_SIZE(((void *)(bp) - DSIZE))) Size_ t size = GET SIZE(HDRP(NEXT_BLKP(bp)));
59
mm_init() Figure 10.46 P747 1 int mm_init(void) 2 {
2 { 3 /* create the initial empty heap */ 4 if ((heap_listp = mem_sbrk(4*WSIZE)) == NULL) 5 return -1; 6 PUT(heap_listp, 0); /* alignment padding */ 7 PUT(heap_listp+WSIZE, PACK(OVERHEAD, 1)); /* prologue header */ 8 PUT(heap_listp+DSIZE, PACK(OVERHEAD, 1)); /* prologue footer */ 9 PUT(heap_listp+WSIZE+DSIZE, PACK(0, 1)); /* epilogue header */ 10 heap_listp += DSIZE; 11 12 /* Extend the empty heap with a free block of CHUNKSIZE bytes */ 13 if (extend_heap(CHUNKSIZE/WSIZE) == NULL) 14 return -1; 15 return 0; 16 }
60
mm_init() Figure 10.47 P748 1 static void *extend_heap(size_t words)
2 { 3 char *bp; 4 size_t size; 5 6 /* Allocate an even number of words to maintain alignment */ 7 size = (words % 2) ? (words+1) * WSIZE : words * WSIZE; 8 if ((int)(bp = mem_sbrk(size)) < 0) 9 return NULL; 10 11 /* Initialize free block header/footer and the epilogue header */ 12 PUT(HDRP(bp), PACK(size, 0)); /* free block header */ 13 PUT(FTRP(bp), PACK(size, 0)); /* free block footer */ 14 PUT(HDRP(NEXT_BLKP(bp)), PACK(0, 1)); /* new epilogue header */ 15 16 /* Coalesce if the previous block was free */ 17 return coalesce(bp); 18 }
61
mm_free() Figure 10.48 P749 1 void mm_free(void *bp) 2 {
2 { 3 size_t size = GET_SIZE(HDRP(bp)); 4 5 PUT(HDRP(bp), PACK(size, 0)); 6 PUT(FTRP(bp), PACK(size, 0)); 7 coalesce(bp); 8 } 9
62
mm_free() 10 static void *coalesce(void *bp) 11 {
11 { 12 size_t prev_alloc = GET_ALLOC(FTRP(PREV_BLKP(bp))); 13 size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp))); 14 size_t size = GET_SIZE(HDRP(bp)); 15 16 if (prev_alloc && next_alloc) { /* Case 1 */ 17 return bp; 18 } 19 20 else if (prev_alloc && !next_alloc) { /* Case 2 */ 21 size += GET_SIZE(HDRP(NEXT_BLKP(bp))); 22 PUT(HDRP(bp), PACK(size, 0)); 23 PUT(FTRP(bp), PACK(size,0)); 24 return(bp); 25 } 26
63
mm_free() Figure P749 27 else if (!prev_alloc && next_alloc) { /* Case 3 */ 28 size += GET_SIZE(HDRP(PREV_BLKP(bp))); 29 PUT(FTRP(bp), PACK(size, 0)); 30 PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); 31 return(PREV_BLKP(bp)); 32 } 33 34 else { /* Case 4 */ 35 size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(FTRP(NEXT_BLKP(bp))); 37 PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); 38 PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0)); 39 return(PREV_BLKP(bp)); 40 } 41 }
64
mm_malloc() Figure 10.49 P750 1 void *mm_malloc (size_t size) 2 {
2 { 3 size_t asize; /* adjusted block size */ 4 size_t extendsize; /* amount to extend heap if no fit */ 5 char *bp; 6 7 /* Ignore spurious requests */ 8 if (size <= 0) 9 return NULL; 10 11 /* Adjust block size to include overhead and alignment reqs. */ 12 if (size <= DSIZE) 13 asize = DSIZE + OVERHEAD; 14 else 15 asize = DSIZE * ((size + (OVERHEAD) + (DSIZE-1)) / DSIZE); 16
65
mm_malloc() 17 /* Search the free list for a fit */
18 if ((bp = find_fit(asize)) != NULL) { 19 place (bp, asize); 20 return bp; 21 } 22 23 /* No fit found. Get more memory and place the block */ 24 extendsize = MAX (asize, CHUNKSIZE) ; 25 if ((bp = extend_heap (extendsize/WSIZE)) == NULL) 26 return NULL; 27 place (bp, asize); 28 return bp; 29 }
66
mm_alloc() problem 10.8 static void *find_fit(size_t asize) {
void *bp ; /* first fit search */ for (bp = heap_listp; GET_SIZE(HDRP(bp)) > 0 ; bp = NEXT_BLKP(bp) ) { if (!GET_ALLOC(HDRP(bp)) && (asize<=GET_SIZE(HDRP(bp)))) { return bp; } return NULL; /*no fit */
67
mm_alloc() problem 10.9 static void place(void *bp, size_t asize) {
size_t csize = GET_SIZE(HDRP(bp)) ; if ( (csize –asize) >= (DSIZE + OVERHEAD) ) { PUT(HDRP(bp), PACK(asize, 1)) ; PUT(FTRP(bp), PACK(asize, 1)) ; bp = NEXT_BLKP(bp) ; PUT(HDRP(bp), PACK(csize-asize, 0) ; PUT(FTRP(bp), PACK(csize-asize, 0) ; } else { PUT(HDRP(bp), PACK(csize, 1) ; PUT(FTRP(bp), PACK(csize, 1) ; }
68
Explicit Free Lists
69
Use data space for link pointers
Explicit free lists Explicit list among the free blocks using pointers within the free blocks Use data space for link pointers Typically doubly linked Still need boundary tags for coalescing It is important to realize that links are not necessarily in the same order as the blocks
70
Explicit free lists A B C 4 6 Forward links Back links A B C
71
Freeing with explicit free lists
Where to put the newly freed block in the free list 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.
72
Freeing with explicit free lists
Where to put the newly freed block in the free list Address-ordered policy insert freed blocks so that free list blocks are always in address order i.e. addr(pred) < addr(curr) < addr(succ) con: requires search pro: studies suggest fragmentation is better than LIFO
73
Segregated Free Lists
74
Each size “class” has its own collection of blocks
Segregated Storage Each size “class” has its own collection of blocks Often have separate collection for every small size (2,3,4,…) For larger sizes typically have a collection for each power of 2
75
Segregated Storage 1-2 3 4 5-8 9-16
76
1) Simple segregated storage
Separate heap and free list for each size class No splitting To allocate a block of size n: if free list for size n is not empty, allocate first block on list (note, list can be implicit or explicit) if free list is empty, get a new page create new free list from all blocks in page allocate first block on list constant time
77
Simple segregated storage
To free a block: Add to free list If page is empty, return the page for use by another size (optional) Tradeoffs: fast, but can fragment badly
78
2) Segregated fits Array of free lists, each one for some size class
79
To allocate a block of size n:
Segregated fits 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 blocks is found in all classes, try more heap memory
80
Segregated fits To free a block: Tradeoffs
coalesce and place on appropriate list (optional) Tradeoffs faster search than sequential fits (i.e., log time for power of two size classes) controls fragmentation of simple segregated storage coalescing can increase search times deferred coalescing can help
81
A special case of segregated fits
3) Buddy Systems A special case of segregated fits Each size is power of 2 Initialize A heap of size 2m
82
Buddy Systems Allocate Free Roundup to power of 2 such as 2k
Find a free block of size 2j (k j m) Split the block in half until j=k Each remaining half block (buddy) is placed on the appreciate free list Free Continue coalescing with the free buddies
83
Garbage Collection
84
10.10.1 Garbage Collector Basics
85
Garbage Collector’s View of Memory as a Directed Graph
Nodes Root Nodes Heap Nodes Reachable Not-reachable (garbage) Directed Edge
86
Garbage Collector Maintain some representation of the reachability graph Periodically reclaim the unreachable nodes by freeing them and returning them to the free list
87
Conservative Garbage Collector
Each reachable block is correctly identified as reachable Some unreachable nodes might be incorrectly identified as reachable
88
Garbage Collector On demand
Run as separate threads in parallel with the application Figure P756
89
10.10.2 Mark&Sweep Garbage Collectors
90
Functions prt isPtr(ptr p) int blockMarked(ptr b)
int blockAllocated(ptr b) void markBlock(ptr b) int length(b) void unmarkBlock(ptr b) prt nextBlock(ptr b)
91
10.10.3 Conservative Mark&Sweep for C Programs
92
10.11 Common Memory-Related Bugs in C Programs
93
10.11.1 Dereferencing Bad Pointers
94
Example scanf(‘’%d”, &val); scanf(‘’%d”, val);
95
10.11.2 Reading Uninitialized Memory
96
Error Assume heap memory is initialized to zero
97
10.11.3 Allowing Stack Buffer Overflows
98
Buffer Overflow Bug void bufoverflow() { char buf[64]; gets(buf);
return; }
99
10.11.4 Assuming that Pointers and the Objects they Point to Are the Same Size
100
Common Mistake Assume that pointers to objects are the same size as the objects they point to
101
10.11.5 Making Off-by-One Errors
102
Overwriting Bugs int **makeArray2(int n, int m) { int I;
int **A=(int **)Malloc(n*sizeof(int)); for (i=0; i<=n; i++) A[i] = (int *)Malloc(m*sizeof(int)); return A; }
103
10.11.6 Referencing a Pointer Instead of the Object it Points to
104
Precedence and associativity of C operators
int *binheapDelete(int **binheap, int *size) { int *packet = binheap[0]; binheap[0] = binheap[*size-1]; *size--; heapify(binheap, *size, 0); return(packet); }
105
10.11.7 Misunderstanding Pointer Arithmetic
106
Common mistake Forget that arithmetic operations on pointers are performed in units that are the size of the objects they point to, which are not necessarily bytes int *search(int *p, int val) { while (*p && *p != val) p += sizeof(int); return p; }
107
10.11.8 Referencing Nonexisted Variables
108
Discipline The stack discipline will sometimes reference local variables that are no longer valid int *stackref() { int val; return &val; }
109
10.11.9 Referencing Data in Free Heap Blocks
110
Error To reference data in heap blocks that have already been freed
int *heapref(int n, int m) { int i; int *x, *y; x = (int *) Malloc(n * sizeof(int)); free(x); y = (int *) Malloc(m * sizeof(int)); for (i=0; i<m; i++) y[i] = x[i]++; return y; }
111
10.11.10 Introducing Memory Leaks
112
Error Create garbage in the heap by forgetting to free all allocated blocks void leak (int n) { int *x = (int *) Malloc(n * sizeof(int)); return; }
113
10.12 Recapping Some Key Ideas About Virtual Memory
114
Summary
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.