Washington WASHINGTON UNIVERSITY IN ST LOUIS Memory Management Fred Kuhns Applied Research Laboratory, Department of Computer Science and Engineering, Washington University in St. Louis
2 Fred Kuhns (7/24/2015)CS422 – Operating Systems Concepts The Big Picture Swap UFS app1 Disk DRAM CPU Unitialized data Allocated virtual pages Text and initialized data Stack and heap app1 Address space Low Address (0x ) High Address (0x7fffffff) Initialized Data Text (shared) Unitialized Data Heap (Dynamic) stack (dynamic) Environment
3 Fred Kuhns (7/24/2015)CS422 – Operating Systems Concepts Your Programs Address Space Process Address space Low Address (0x ) High Address (0x7fffffff) Initialized Data Text (shared) Unitialized Data Heap (Dynamic) stack (dynamic) Environment Local variables, example, function calls Global: dynamically allocated (allocate with new/malloc) Global: int x = 4; Global: int y; Code:int main(){…} void fn(){…} MyClass::doit(){…}
4 Fred Kuhns (7/24/2015)CS422 – Operating Systems Concepts Buddy System: Example Memory Allocator B Bitmap (32 B chunks) FreeIn-use Free list allocate(256), allocate(128), allocate(64), allocate(128), release(C, 128), release (D, 64) CDDFFE
5 Fred Kuhns (7/24/2015)CS422 – Operating Systems Concepts C-Style memory allocation - alloc malloc() and related functions –void *malloc(size_t) –void *calloc(size_t, size_t) –void free(void *) Allocate memory from the heap implementation will request memory pages (usually 4KB) from OS then divide this into allocation blocks for example a simple buddy- system allocator Text (shared) Data Heap (Dynamic) stack (dynamic) main() locals obj1->something() obj->doit() malloc(b_bytes) MyStruct *m = (MyStruct *)malloc(sizeof(MyStruct));
6 Fred Kuhns (7/24/2015)CS422 – Operating Systems Concepts C-Style memory allocation - free when free() is called the memory is returned to the free store and is eligible to be re- allocated. Text (shared) Data Heap (Dynamic) stack (dynamic) main() locals obj1->something() obj->doit() free(b_bytes) free(m);
7 Fred Kuhns (7/24/2015)CS422 – Operating Systems Concepts C++ Style (an example using malloc/free) new/delete operators when the compiler encounters a new operator: –it first allocates memory from the free store, for example using malloc() –second it calls the object constructor when compiler encounters the delete operator it: –call the object destructor –it returns memory to the free store, for example using free() Text (shared) Data Heap (Dynamic) stack (dynamic) main() locals obj1->something() obj->doit() data for object MyClass Psuedo C++ simulating new MyClass void *m = malloc(sizeof(MyClass)); MyClass::MyClass(this=m); malloc(b_bytes)
8 Fred Kuhns (7/24/2015)CS422 – Operating Systems Concepts when delete is called,the compiler will first call the objects destructor before freeing the memory (i.e. return memory to the free store) Text (shared) Data Heap (Dynamic) stack (dynamic) main() locals obj1->something() obj->doit() free(b_bytes) Psuedo C++ simulating delete m MyClass::~MyClass( this=m ); free(m); C++ Style (an example using malloc/free)
9 Fred Kuhns (7/24/2015)CS422 – Operating Systems Concepts Operator new and delete Any class may override these operators. They are implicitly static members. Derived classes necessarily inherit these operators Operator new() always has at least one argument (implicit), the number of bytes to allocate: void *operator new (size_t); Operator delete() has two arguments, the objects address and its size in bytes. void delete(void*, size_t); For the array versions the size argument is for the total number of bytes to allocate: void *operator new[](size_t); void operator delete[](void*, size_t)
10 Fred Kuhns (7/24/2015)CS422 – Operating Systems Concepts An Example class Base { public: int i; Base() : i(0) {} virtual ~Base(){} // objects void *operator new (size_t n){ return (void *)malloc(n);} void operator delete(void *p, size_t n) {free(p);return;} // Arrays void *operator new[] (size_t n) {return (void *)malloc(n);} void operator delete[] (void *p, size_t n){free(p); return;} }; class Derived : public Base { public: int b; Derived() : b(0){} ~Derived() {} };
11 Fred Kuhns (7/24/2015)CS422 – Operating Systems Concepts Observations The base class must declare its destructor to be virtual. Why? What happens if it doesnt The C++ environment keeps track of the objects size when calling delete – hint for the answer above we should throw bad_alloc() if unable to allocate memory
12 Fred Kuhns (7/24/2015)CS422 – Operating Systems Concepts Operator new and exceptions operator new throws bad_alloc if it is unable to allocate memory void *operator new(size_t size) { for (;;) { if (void* p = malloc(size)) return p; if (_new_handler == 0) throw bad_alloc(); _new_handler(); } You can set the new_handler with a call to set_new_handler() declared in. effective strategy is to attempt freeing resources but if unable then either throw bad_alloc() yourself or remove your new_handler to operator new will.
13 Fred Kuhns (7/24/2015)CS422 – Operating Systems Concepts placement syntax You can supply extra arguments to new void * operator new(size_t, void* p) {return p;} void *buf = reinterpret_cast (0xfoof); X* p2=new(buf)X; The call to new will return the address buf class Arena { public: virtual void* alloc(size_t) = 0; virtual void free(virtual*) = 0; … }; void * operator new(size_t n, Arena* a) { return a->alloc(n);} X* ptr = new(MyArena) X(…); The delete operator can also be overloaded but it will only be called implicitly if the corresponding new operator throws an exception. Otherwise delete is not called. The best strategy is to define a destroy() function that calls the destructor() and free() methods explicitly. void destroy(X* p, Arean* a) { p->~X(); a->free(p); }