heap management
DESCRIPTION
Heap Management. What is really stored on the heap?. 0x7000. Housekeeping Users Data Buffer Next Block Data Housekeeping. 0x7008. int main() { int *x,*y; x=(int*)malloc(2*sizeof(int)); //new heap - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/1.jpg)
Heap Management
![Page 2: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/2.jpg)
What is really stored on the heap?
Housekeeping Users Data Buffer Next BlockData Housekeeping
0x7000
0x7008
int main() { int *x,*y; x=(int*)malloc(2*sizeof(int)); //new heap assert(x); printf("%p\n",x);
//How does malloc function know where to put y? y=(int*)malloc(sizeof(int)); assert(y); //How does free function know how much to free? free(x);
![Page 3: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/3.jpg)
What is really stored on the heap?
"housekeeping data" stored in area before your data:size field- holds the number of bytes of users data in this block (user's request + some buffer)
next field- if block in "use" it will be null.. otherwise holds the address of the next free block..
Thus a "linked list" of free blocks is formed inside the heap. Starting at address given by the "free list pointer".. malloc can search through free blocks.
Housekeeping Users Data Buffer Next BlockData Housekeeping
0x7000
0x7008
![Page 4: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/4.jpg)
What is really stored on the heap?
A "reference count" of number of pointers pointing to this block in user's program could also be in the housekeeping data.
What would we use the reference count for?
Housekeeping Users Data Buffer Next BlockData Housekeeping
0x7000
0x7008
![Page 5: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/5.jpg)
What does the heap look like?
malloc() searches the free list for a block that is big enough. If none is found, more memory is requested from the operating system.
free() checks if the blocks adjacent to the freed block are also free
If so, adjacent free blocks are merged in to a single, larger free block.Otherwise, the freed block is just added to the free list.
![Page 6: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/6.jpg)
What does the heap look like?
• If there are multiple free blocks of memory that are big enough for some request, how do we choose which one to use?– best-fit: choose the smallest block that is big enough
for the request
– first-fit: choose the first block we see that is big enough
– next-fit: like first-fit but remember where we finished searching and resume searching from there
![Page 7: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/7.jpg)
What does the heap look like?
int main() { int *x,*y,*z; x=(int*)malloc(20*sizeof(int)); //new heap assert(x);
y=(int*)malloc(10*sizeof(int)); assert(y); free(x);
z=(int*)malloc(10*sizeof(int)); assert(z);
What does our heap look like if we use first fit?What if we use next fit?
![Page 8: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/8.jpg)
the heap starts here at 7000 x=7008 this is 92 bytes here
size=92 bytes next free block20*4 + 12 buffer NULL
20 integers and 12 bytes of buffer...
size=52 bytes next free block10*4 + 12 buffer NULL
7100 y=7108 this is 52 bytes here
10 integers and 12 bytes of buffer...
size=xxxx bytes next free block(heap size-160) NULL
7160 this is heap size - 168 bytes here
Heap Free List Pointer = 7160
The Heap looks like this after malloc'ing x and y before x is freed.
![Page 9: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/9.jpg)
the heap starts here at 7000 this is 92 bytes here
size=92 bytes next free block20*4 + 12 buffer NULL
FREE FREE FREE FREE FREE FR
size=52 bytes next free block10*4 + 12 buffer NULL
7100 y=7108 this is 52 bytes here
10 integers and 12 bytes of buffer...
size=xxxx bytes next free block(heap size-160) NULL
7160 this is heap size - 168 bytes here
Heap Free List Pointer = 7000
The Heap looks like this x is freed before z is malloc'ed.
![Page 10: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/10.jpg)
the heap starts here at 7000 z=7008 this is 52 bytes here
size=52 bytes next free block20*4 + 12 buffer NULL
10 integers and 12 bytes of buffer...
size=32 bytes next free block 7160
7060 this is 32 bytes here
FREE FREE FREE FREE FREE
size=xxxx bytes next free block(heap size-160) NULL
7160 this is heap size - 168 bytes here
size=52 bytes next free block10*4 + 12 buffer NULL
7100 y=7108 this is 52 bytes here
10 integers and 12 bytes of buffer...
Heap Free List Pointer = 7060
![Page 11: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/11.jpg)
the heap starts here at 7000 this is 92 bytes here
size=92 bytes next free block 7220
FREE FREE FREE FREE FREE
size=xxxx bytes next free block(heap size-220) NULL
7220 this is heap size - 220 bytes here
size=52 bytes next free block10*4 + 12 buffer NULL
7100 y=7108 this is 52 bytes here
10 integers and 12 bytes of buffer...
Heap Free List Pointer = 7000
size=52 bytes next free block10*4 + 12 buffer NULL
7160 z=7168 this is 52 bytes here
10 integers and 12 bytes of buffer...
![Page 12: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/12.jpg)
GNU malloc.c- Simplified for old ver.
![Page 13: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/13.jpg)
_heapinfo[0]
_heapinfo[1]
…
_heapinfo[210-1]
4th block
5st block
6nd block
7rd block
8th block
9th block
…
…
HEAP = 222 bytes
BLOCKSIZE
= 212 bytes
_heapbase
0 0
1 0
2 0
3 3
4 2
5 0
6 0
7 0
8 0
9 0
10 0
11 0
_fragblocks
0 next prev
1 next prev
2 next prev
3 next prev
4 next prev
5 next prev
6 next prev
7 next prev
8 next prev
9 next prev
10 next prev
11 next prev
_fraghead
0
12
24
12288
16376
20484
Data Structure for malloc.c
![Page 14: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/14.jpg)
_fragblocks• A global array of 12 integers holds the number of
4096 bytes blocks containing fragments of a certain size that have been allocated. [11] is number of 4096 byte blocks containing 2048 byte fragments… [10] is number of 4096 bytes blocks containing for 1024 byte fragments
• Note that frag here is allocated frag, not free frag.
int _fragblocks[BLOCKLOG];
//BLOCKLOG = log2(BLOCKSIZE)
![Page 15: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/15.jpg)
_fradhead• A global array of 12 structures holds the
pointer to the first and the last frag block of a given size: 2log
• Note that frag here is free frag.
struct list _fraghead[BLOCKLOG];//list{int *next; int prev;}
NEXT PREV NEXT NEXT NEXTPREV PREV PREV
0 0
_fraghead[log]
![Page 16: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/16.jpg)
How the real malloc does it…
• The real malloc actually uses blocks of standardized size to fill your request.– The standard block is 4096 bytes.
– Standard blocks can be broken up in to smaller “frag blocks” of sizes 8, 16, 32, 64, 128, 256, 512, 1024, 2048 bytes long.
– For example:• If you ask for 13 bytes you’ll get a 16 byte fragment.
– This is a trade off between speed and space wastage.
Why the smallest free frag size is 8?
Why not 4 or other number?
![Page 17: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/17.jpg)
_heapinfo
• busy– fragmented
• type: frag size• num of free frag• first free frag
– allocated as whole• type: a block• the num of contiguous blocks which are allocated
• free– the num of contiguous blocks which are free– next free cluster – prev free cluster
![Page 18: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/18.jpg)
Look at source code – malloc.h
• $tar –xvf malloc_debug.tar
• $cd malloc_debug/malloc
• $vim malloc.h
![Page 19: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/19.jpg)
externWhat if I want global variables to be accessible for use in
another file (section of my code)?extern int flag;
extern- lets the compiler know that it won’t be able to figure out where the variable is located at compile time. (unresolved reference)
Why? The compiler only looks at the file you are trying to compile- and doesn’t have the “big picture” yet about the other files you’re compiling and putting together. NACHOS will have about 30 source files that you will compile to build the OS. (LINUX kernel has 100s)
![Page 20: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/20.jpg)
extern continuedThe Linker does have the “big picture” and
responsible for “linking” together all of the object files made by the compiler and making a single executable.
In the case of extern the compiler will send a message to the linker saying
“I’m not really sure where this variable is located- it may be in another file - can you find it?”
![Page 21: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/21.jpg)
Function Pointerstypedef enum bool {FALSE, TRUE} bool;
bool greaterthan(int x,int y) {return (x>y);
}bool lessthan(int x, int y) { return (x<y);}
bool foo(bool (*compare)(int,int), int x, int y){ return( (*compare)(x,y));}
int main(){ if (foo(lessthan,3,5)) printf("3 is less than 5\n");}
![Page 22: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/22.jpg)
Function Pointers#include <stdio.h>void function (int x) {printf("%d",x);}
void (*func_pointer)(int);
int main(){ int choice;
int x = 5;
void (*func_pointer)(int) = function;
(*func_pointer)(int);}
![Page 23: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/23.jpg)
Function PointersTo declare a function pointer :return type (*function_ptr) (function inputs);
extern void *(*_morecore)(long);
extern- this function may be defined or used outside this file
The return type is a void*The input to the function must be a long.The function is referred to via the pointer _morecore
![Page 24: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/24.jpg)
This is a function prototype:
/* Default value of previous. */extern void *_default_morecore(long);
This function takes in a long and returns a void* and is called _default_morecore
This matches the type of a _morecore function pointer.
The _default_morecore function actually goes and gets more memory for the heap.
![Page 25: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/25.jpg)
Function Pointers cont’dSo far we’ve declared a function pointer
extern void *(*_morecore)(long);
We’ve given a function prototype
extern void *_default_morecore(long)
And then we eventually assign the pointer…
Code from malloc.c
/* How to really get more memory. */
void *(*_morecore)(long) = _default_morecore;
![Page 26: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/26.jpg)
What do these do?#define INT_BIT (CHAR_BIT * sizeof (int))
You may assume that CHAR_BIT is 8 in our architecture.
#define BLOCKLOG (INT_BIT > 16 ? 12 : 9)
What value does BLOCKLOG get?
#define BLOCKSIZE (1 << BLOCKLOG)
What value does BLOCKSIZE get? Shift left 1 how many times?
#define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE)
![Page 27: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/27.jpg)
Heap Initial Size
/* Determine the amount of memory spanned by the initial heap table (not an absolute limit). */
#define HEAP (INT_BIT > 16 ? 4194304 : 65536)
![Page 28: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/28.jpg)
Unions• Most of the programmers in the world think that
Unions were a bad idea. That’s probably why Java got rid of them. Unfortunately- there’s lots of poorly written code out there with unions in it. Including malloc()
• Unions allow you to store one of several different types in a given storage location.
• Unfortunately- you have to remember which type that you stored in the location.
![Page 29: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/29.jpg)
Union Exampletypedef union Number {int x;double y;
} Number_T;
int main() { Number_T value; value.x=100; printf ("X is %d and Y is %g\n", value.x,value.y);
value.y=100.0; printf ("X is %d and Y is %g\n", value.x,value.y);
}
X is 100 and Y is 6.15928e-306X is 0 and Y is 100.000000
Thus in a Number_T we can store either an int or a double and can change back and forth
![Page 30: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/30.jpg)
union info { struct { int type; union { struct { int nfree; int first; } frag;
int size; } info;
} busy; struct { int size; int next; int prev; } free;};
An info is either:
This (busy struct)
Or
This (free struct)
![Page 31: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/31.jpg)
union info { struct { int type; union { struct { int nfree; int first; } frag;
int size; } info;
} busy; struct { int size; int next; int prev; } free;};
A busy is:an integerAnd either:frag structureor another integer
![Page 32: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/32.jpg)
What does this do?
#define BLOCK(A) (((char *) (A) - _heapbase) / BLOCKSIZE + 1)
#define ADDRESS(B) ((void *) (((B) - 1) * BLOCKSIZE + _heapbase))
![Page 33: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/33.jpg)
Debug malloc.c
• $ cd ~/malloc_debug
• $ddd main
• Menu ‘data’->’Status Display’– Backtrace of the stack
• Menu ‘Edit’->’Preferences…’->’Source’– Display Source Line Numbers
![Page 34: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/34.jpg)
main.c
• //Allocate the first memory under your control.
• int *x;
//new heap
• x=(int*)malloc(20*sizeof(int));
• free(x);
![Page 35: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/35.jpg)
Step into malloc func
HEAP = 222 bytes
BLOCKSIZE
= 212 bytes
_heapbase
0 0
1 0
2 0
3 0
4 0
5 0
6 0
7 0
8 0
9 0
10 0
11 0
_fragblocks
0 next prev
1 0 0
2 0 0
3 0 0
4 0 0
5 0 0
6 0 0
7 0 0
8 0 0
9 0 0
10 0 0
11 0 0
_fraghead
![Page 36: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/36.jpg)
Step into initialize()
• heapsize = HEAP / BLOCKSIZE;– Figures out how many blocks we have
• We have 210 blocks.
• In other words, 210 _heapinfo elements.
![Page 37: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/37.jpg)
align(heapsize * sizeof (union info));
HEAP = 222 bytes
BLOCKSIZE
= 212 bytes
_heapbase
0 0
1 0
2 0
3 0
4 0
5 0
6 0
7 0
8 0
9 0
10 0
11 0
_fragblocks
0 next prev
1 0 0
2 0 0
3 0 0
4 0 0
5 0 0
6 0 0
7 0 0
8 0 0
9 0 0
10 0 0
11 0 0
_fraghead_heapinfo[0]
_heapinfo[1]
…
_heapinfo[210-1]
0
12
24
![Page 38: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/38.jpg)
_heapbase = (char *) _heapinfo;
HEAP = 222 bytes
BLOCKSIZE
= 212 bytes
_heapbase
0 0
1 0
2 0
3 0
4 0
5 0
6 0
7 0
8 0
9 0
10 0
11 0
_fragblocks
0 next prev
1 0 0
2 0 0
3 0 0
4 0 0
5 0 0
6 0 0
7 0 0
8 0 0
9 0 0
10 0 0
11 0 0
_fraghead_heapinfo[0]
_heapinfo[1]
…
_heapinfo[210-1]
0
12
24
![Page 39: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/39.jpg)
Go back to malloc
126: Check for request for 0 bytes
129: Check to see if size requested is < 8 Bytes
133: Is the request <= 2048 bytes?
![Page 40: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/40.jpg)
136: --size;137: for (log=1; (size>>=1)!=0; ++log)
• At the end the following will be true:• 2log >= size > 2log-1
• For example:• size = 80• in binary size = 1010000• --size = 1001111• log = 7
• Why --size?
![Page 41: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/41.jpg)
142: if ((next = _fraghead[log].next) != 0)
• We check to see if there are any frag blocks of our size available. (Initially no frag blocks. _fraghead[log].next is all 0’s because…)
![Page 42: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/42.jpg)
158: result = malloc(BLOCKSIZE)
• We make a recursive call to malloc requesting a block of 4096 bytes.
• Step into malloc again.
• We do same checks (initialize, size, etc.)
• We go in to large block routine – 179: else
![Page 43: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/43.jpg)
184: blocks = BLOCKIFY(size)
• We get the number of blocks this size corresponds to.
• In our case:– size = 4096– blocks = 1
![Page 44: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/44.jpg)
187: start = block = _heapindex
• _heapindex points the free block which is in the free block link.
_heapinfo[0] _heapinfo[9]
_heapinfo[17] _heapinfo[12]
_heapinfo[7]_heapinfo[3]
_heapindex
![Page 45: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/45.jpg)
188: if (block == start)
• We searched through the linked list, and did not find any memory block large enough to meet our request.
• We need to get more memory from system.
![Page 46: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/46.jpg)
line 193 -- 203
Suppose we need 4 more blocks
_heapinfo[0]
_heapinfo[1]
…
_heapinfo[210-1]
4th block
5st block
6nd block
7rd block
_heapinfo[0]
_heapinfo[1]
…
_heapinfo[210-1]
4th block
5st block
6nd block
7rd block
8th block
9th block
We just need to ask for 2 more.
![Page 47: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/47.jpg)
204: result = morecore(blocks * BLOCKSIZE)
_heapbase
0 0
1 0
2 0
3 0
4 0
5 0
6 0
7 0
8 0
9 0
10 0
11 0
_fragblocks
0 next prev
1 0 0
2 0 0
3 0 0
4 0 0
5 0 0
6 0 0
7 0 0
8 0 0
9 0 0
10 0 0
11 0 0
_fraghead_heapinfo[0]
_heapinfo[1]
…
_heapinfo[210-1]
1st Block
0
12
24
result
![Page 48: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/48.jpg)
Go back to malloc again!
• Now we are at line 158
• 161: ++_fragblocks[log]– We increase the count of our fragment sized blocks
by one.
![Page 49: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/49.jpg)
Line 164 -171
0NEXT PREV
31 frags
each frag has 128 bytes
1st block
0 next prev
1 0 0
2 0 0
3 0 0
4 0 0
5 0 0
6 0 0
7 0
8 0 0
9 0 0
10 0 0
11 0 0
_fraghead
NEXT PREV
NEXT PREV
NEXT PREV
NEXT PREV
0
![Page 50: Heap Management](https://reader035.vdocuments.net/reader035/viewer/2022062408/568137de550346895d9f7ec0/html5/thumbnails/50.jpg)
Line 174 - 177
• Fill in _heapinfo.
• Return the result.
• Done!