Heap Management. What is really stored on the heap? Housekeeping Users Data Buffer Next Block Data Housekeeping 0x7000 0x7008 int main() { int *x,*y;

Slides:



Advertisements
Similar presentations
Memory Management Chapter FourteenModern Programming Languages, 2nd ed.1.
Advertisements

CS 11 C track: lecture 7 Last week: structs, typedef, linked lists This week: hash tables more on the C preprocessor extern const.
Dynamic memory allocation
C Language.
Dynamic Memory Allocation in C.  What is Memory What is Memory  Memory Allocation in C Memory Allocation in C  Difference b\w static memory allocation.
CSC 270 – Survey of Programming Languages C Lecture 6 – Pointers and Dynamic Arrays Modified from Dr. Siegfried.
David Notkin Autumn 2009 CSE303 Lecture 13 This space for rent.
Programming and Data Structure
Unions The storage referenced by a union variable can hold data of different types subject to the restriction that at any one time, the storage holds data.
What is a pointer? First of all, it is a variable, just like other variables you studied So it has type, storage etc. Difference: it can only store the.
The Linux Kernel: Memory Management
Memory Management Chapter 7.
CS1061: C Programming Lecture 21: Dynamic Memory Allocation and Variations on struct A. O’Riordan, 2004, 2007 updated.
User-Level Memory Management in Linux Programming
Kernighan/Ritchie: Kelley/Pohl:
Memory allocation CSE 2451 Matt Boggus. sizeof The sizeof unary operator will return the number of bytes reserved for a variable or data type. Determine:
Discussion: Week 3/26. Structs: Used to hold associated data together Used to group together different types of variables under the same name struct Telephone{
POINTER Prepared by MMD, Edited by MSY1.  Basic concept of pointers  Pointer declaration  Pointer operator (& and *)  Parameter passing by reference.
Memory Management Chapter 7. Memory Management Subdividing memory to accommodate multiple processes Memory needs to be allocated efficiently to pack as.
Memory Management Subdividing memory to accommodate multiple processes Memory needs to be allocated to ensure a reasonable supply of ready processes to.
Allocating Memory.
Informática II Prof. Dr. Gustavo Patiño MJ
C Programming - Lecture 7 This lecture we will learn: –How to write documentation. Internal docs. External docs. User docs. (But not much about this).
Dynamic Data Structures H&K Chapter 14 Instructor – Gokcen Cilingir Cpt S 121 (July 26, 2011) Washington State University.
Dynamic Memory Allocation in C++. Memory Segments in C++ Memory is divided in certain segments – Code Segment Stores application code – Data Segment Holds.
C For Java Programmers Tom Roeder CS sp. Why C? The language of low-level systems programming  Commonly used (legacy code)  Trades off safety.
1 1 Lecture 4 Structure – Array, Records and Alignment Memory- How to allocate memory to speed up operation Structure – Array, Records and Alignment Memory-
Memory Management Memory Areas and their use Memory Manager Tasks:
CS61C L06 C Memory Management (1) Garcia, Spring 2008 © UCB Lecturer SOE Dan Garcia inst.eecs.berkeley.edu/~cs61c CS61C :
Memory Management Chapter 5.
CS61C L06 C Memory Management (1) Garcia, Fall 2006 © UCB Lecturer SOE Dan Garcia inst.eecs.berkeley.edu/~cs61c CS61C : Machine.
1 Inner Workings of Malloc and Free Professor Jennifer Rexford COS 217.
CS61C Midterm Review on C & Memory Management Fall 2006 Aaron Staley Some material taken from slides by: Michael Le Navtej Sadhal.
1 Pointers, Dynamic Data, and Reference Types Review on Pointers Reference Variables Dynamic Memory Allocation –The new operator –The delete operator –Dynamic.
Pointers Applications
1 Procedural Concept The main program coordinates calls to procedures and hands over appropriate data as parameters.
Memory Allocation CS Introduction to Operating Systems.
C Course Lecture 4 This lecture we'll talk about: Multi-dimensional arrays. Pointer arithmetic. Pointers to structures. Multi-file programming. What is.
CS 11 C track: lecture 5 Last week: pointers This week: Pointer arithmetic Arrays and pointers Dynamic memory allocation The stack and the heap.
IT253: Computer Organization Lecture 3: Memory and Bit Operations Tonga Institute of Higher Education.
Stack and Heap Memory Stack resident variables include:
Chapter 0.2 – Pointers and Memory. Type Specifiers  const  may be initialised but not used in any subsequent assignment  common and useful  volatile.
Dynamic Memory Allocation The process of allocating memory at run time is known as dynamic memory allocation. C does not Inherently have this facility,
ICS 145B -- L. Bic1 Project: Main Memory Management Textbook: pages ICS 145B L. Bic.
Computer Science and Software Engineering University of Wisconsin - Platteville 2. Pointer Yan Shi CS/SE2630 Lecture Notes.
University of Washington Today Finished up virtual memory On to memory allocation Lab 3 grades up HW 4 up later today. Lab 5 out (this afternoon): time.
1 C++ Classes and Data Structures Jeffrey S. Childs Chapter 4 Pointers and Dynamic Arrays Jeffrey S. Childs Clarion University of PA © 2008, Prentice Hall.
1 Dynamic Memory Allocation –The need –malloc/free –Memory Leaks –Dangling Pointers and Garbage Collection Today’s Material.
1 Memory Management Chapter 7. 2 Memory Management Subdividing memory to accommodate multiple processes Memory needs to be allocated to ensure a reasonable.
1 CHAPTER 5 POINTER. 2 Pointers  Basic concept of pointers  Pointer declaration  Pointer operator (& and *)  Parameter passing by reference  Dynamic.
Pointers: Basics. 2 What is a pointer? First of all, it is a variable, just like other variables you studied  So it has type, storage etc. Difference:
1 Pointers to structs. 2 A pointer to a struct is used in the same way as a pointer to a simple type, such as an int. Pointers to structs were introduced.
Copyright 2005, The Ohio State University 1 Pointers, Dynamic Data, and Reference Types Review on Pointers Reference Variables Dynamic Memory Allocation.
1 Memory Management Chapter 7. 2 Memory Management Subdividing memory to accommodate multiple processes Memory needs to be allocated to ensure a reasonable.
+ Dynamic memory allocation. + Introduction We often face situations in programming where the data is dynamics in nature. Consider a list of customers.
POINTERS Introduction to Systems Programming - COMP 1002, 1402.
CSCI 156: Lab 11 Paging. Our Simple Architecture Logical memory space for a process consists of 16 pages of 4k bytes each. Your program thinks it has.
CSE 351 Dynamic Memory Allocation 1. Dynamic Memory Dynamic memory is memory that is “requested” at run- time Solves two fundamental dilemmas: How can.
Sudeshna Sarkar, CSE, IIT Kharagpur1 Structure and list processing Lecture
C Tutorial - Pointers CS 537 – Introduction to Operating Systems.
DYNAMIC MEMORY ALLOCATION. Disadvantages of ARRAYS MEMORY ALLOCATION OF ARRAY IS STATIC: Less resource utilization. For example: If the maximum elements.
Dynamic Allocation Review Structure and list processing
Memory Management Memory Areas and their use Memory Manager Tasks:
CS Introduction to Operating Systems
Lecturer SOE Dan Garcia
Memory Allocation CS 217.
Memory Management Overview
Dynamic Memory A whole heap of fun….
Memory Management Memory Areas and their use Memory Manager Tasks:
Pointers, Dynamic Data, and Reference Types
Presentation transcript:

Heap Management

What is really stored on the heap? Housekeeping Users Data Buffer Next Block Data 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);

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 Block Data Housekeeping 0x7000 0x7008

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 Block Data Housekeeping 0x7000 0x7008

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.

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

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?

the heap starts here at 7000 x=7008 this is 92 bytes here size=92 bytes next free block 20* buffer NULL 20 integers and 12 bytes of buffer... size=52 bytes next free block 10* 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 bytes here Heap Free List Pointer = 7160 The Heap looks like this after malloc 'ing x and y before x is free d.

the heap starts here at 7000 this is 92 bytes here size=92 bytes next free block 20* buffer NULL FREE FREE FREE FREE FREE FR size=52 bytes next free block 10* 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 bytes here Heap Free List Pointer = 7000 The Heap looks like this x is free d before z is malloc 'ed.

the heap starts here at 7000 z=7008 this is 52 bytes here size=52 bytes next free block 20* buffer NULL 10 integers and 12 bytes of buffer... size=32 bytes next free block 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 bytes here size=52 bytes next free block 10* buffer NULL 7100 y=7108 this is 52 bytes here 10 integers and 12 bytes of buffer... Heap Free List Pointer = 7060

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 bytes here size=52 bytes next free block 10* 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 block 10* buffer NULL 7160 z=7168 this is 52 bytes here 10 integers and 12 bytes of buffer...

GNU malloc.c - Simplified for old ver.

_heapinfo[0] _heapinfo[1] … _heapinfo[ ] 4 th block 5 st block 6 nd block 7 rd block 8 th block 9 th block … … HEAP = 2 22 bytes BLOCKSIZE = 2 12 bytes _heapbase _fragblocks 0nextprev 1nextprev 2nextprev 3nextprev 4nextprev 5nextprev 6nextprev 7nextprev 8nextprev 9nextprev 10nextprev 11nextprev _fraghead Data Structure for malloc.c

_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 = log 2 (BLOCKSIZE)

_fradhead A global array of 12 structures holds the pointer to the first and the last frag block of a given size: 2 log Note that frag here is free frag. struct list _fraghead[BLOCKLOG]; //list{int *next; int prev;} NEXT PREV NEXT PREV 0 0 _fraghead[log]

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?

_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

Look at source code – malloc.h $tar –xvf malloc_debug.tar $cd malloc_debug/malloc $vim malloc.h

extern What 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)

extern continued The 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?”

Function Pointers typedef 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"); }

Function Pointers #include 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); }

Function Pointers To 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

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.

Function Pointers cont’d So 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;

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)

Heap Initial Size /* Determine the amount of memory spanned by the initial heap table (not an absolute limit). */ #define HEAP (INT_BIT > 16 ? : 65536)

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.

Union Example typedef 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 e-306 X is 0 and Y is Thus in a Number_T we can store either an int or a double and can change back and forth

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)

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 integer And either: frag structure or another integer

What does this do? #define BLOCK(A) (((char *) (A) - _heapbase) / BLOCKSIZE + 1) #define ADDRESS(B) ((void *) (((B) - 1) * BLOCKSIZE + _heapbase))

Debug malloc.c $ cd ~/malloc_debug $ddd main Menu ‘data’->’Status Display’ –Backtrace of the stack Menu ‘Edit’->’Preferences…’->’Source’ –Display Source Line Numbers

main.c //Allocate the first memory under your control. int *x; //new heap x=(int*)malloc(20*sizeof(int)); free(x);

Step into malloc func HEAP = 2 22 bytes BLOCKSIZE = 2 12 bytes _heapbase _fragblocks 0nextprev _fraghead

Step into initialize() heapsize = HEAP / BLOCKSIZE; –Figures out how many blocks we have We have 2 10 blocks. In other words, 2 10 _heapinfo elements.

align(heapsize * sizeof (union info)); HEAP = 2 22 bytes BLOCKSIZE = 2 12 bytes _heapbase _fragblocks 0nextprev _fraghead _heapinfo[0] _heapinfo[1] … _heapinfo[ ]

_heapbase = (char *) _heapinfo; HEAP = 2 22 bytes BLOCKSIZE = 2 12 bytes _heapbase _fragblocks 0nextprev _fraghead _heapinfo[0] _heapinfo[1] … _heapinfo[ ]

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?

136: --size; 137: for (log=1; (size>>=1)!=0; ++log) At the end the following will be true: 2 log >= size > 2 log-1 For example: size = 80 in binary size = size = log = 7 Why --size?

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…)

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

184: blocks = BLOCKIFY(size) We get the number of blocks this size corresponds to. In our case: –size = 4096 –blocks = 1

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

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.

line Suppose we need 4 more blocks _heapinfo[0] _heapinfo[1] … _heapinfo[ ] 4 th block 5 st block 6 nd block 7 rd block _heapinfo[0] _heapinfo[1] … _heapinfo[ ] 4 th block 5 st block 6 nd block 7 rd block 8 th block 9 th block We just need to ask for 2 more.

204: result = morecore(blocks * BLOCKSIZE) _heapbase _fragblocks 0nextprev _fraghead _heapinfo[0] _heapinfo[1] … _heapinfo[ ] 1 st Block result

Go back to malloc again! Now we are at line : ++_fragblocks[log] –We increase the count of our fragment sized blocks by one.

Line NEXT PREV 31 frags each frag has 128 bytes 1 st block 0nextprev _fraghead NEXT PREV NEXT PREV NEXT PREV NEXT PREV 0

Line Fill in _heapinfo. Return the result. Done!