

Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
An overview of memory management in operating systems, focusing on segments, physical and virtual addresses, and allocation techniques. The generation of addresses at compile time, load time, and execution time, as well as uniprogramming, multiprogramming, and relocation. Additionally, it discusses memory allocation using the heap and dynamic allocation techniques like malloc and new.
Typology: Study notes
1 / 3
This page cannot be seen from the preview
Don't miss anything!


CMPSCI 377 Operating Systems Fall 2008
Lecturer: Prashant Shenoy Scribe: Shashi Singh
Memory management is the act of managing computer memory. In its simpler forms, this involves providing ways to allocate portions of memory to programs at their request, and freeing it for reuse when no longer needed. The management of main memory is critical to the computer system. Initially the program exe- cutable is resident on disk. The OS loads the program from the disk into main memory. While executing the program, the CPU fetches instructions and data from memory.
Compile time: The compiler generates the exact physical location in memory starting from some fixed starting position k. The OS is not involved here.
Load time: Compiler generates an address, but at load time the OS determines the process’ starting position. Once the process loads, it does not move in memory.
Execution time: Compiler generates an address, and OS cana place it anywhere in memory.
Perhaps the simplest model for using memory is to provide uniprogramming without memory protection, where each application runs with a hardwired range of physical memory addresses. Given that a uniprogram- ming environment allows only one application to run at a time, an application can use the same physical addresses every time, even across reboots. Typically, applications use the lower memory addresses (low memory), and an operating system uses the higher memory addresses (high memory). An application can address any physical memory location. OS is protected from process by checking addresses used by process.
14-2 Lecture 14: October 21
One step beyond the uniprogramming model is to provide multiprogramming without memory protection. When a program is copied into memory, a linker-loader alters the code of the program (loads, stores, jumps) to use the address of where the program lands in memory. In this environment, bugs in any program can cause other programs to crash, even the operating system. The third model is to have a multiprogrammed operating system with memory protection. Memory protection keeps user programs from crashing one another and the operating system.
The role of relocation, the ability to execute processes independently from their physical location in memory, is central for memory management: virtually all the techniques in this field rely on the ability to relocate processes efficiently. The need for relocation is immediately evident when one considers that in a general- purpose multiprogramming environment a program cannot know in advance (before execution, i.e. at compile time) what processes will be running in memory when it is executed, nor how much memory the system has available for it, nor where it is located. Hence a program must be compiled and linked in such a way that it can later be loaded starting from an unpredictable address in memory, an address that can even change during the execution of the process itself, if any swapping occurs.
It’s easy to identify the basic requirement for a (binary executable) program to be relocatable: all the references to memory it makes during its execution must not contain absolute (i.e. physical) addresses of memory cells, but must be generated relatively, i.e. as a distance, measured in number of contiguous memory words, from some known point. The memory references a program can generate are of two kinds: references to instructions ad references to data. The former kind is implied in the execution of program branches or subroutine calls: a jump machine instruction always involves the loading of the CPU program counter register with the address of the memory word containing the instruction to jump to. The executable code of a relocatable program must then contain only relative branch machine instructions, in which the address to branch to is specified as an increment (or decrement) with respect to the address of the current instruction (or to the content of a register or memory word). The latter kind comes into play when whenever program variables (including program execution variables, like a subroutine call stack) are accessed. In this case relocation is made possible by the use of indexed or increment processor addressing modes, in which the address of a memory word is computed at reference time as the sum of the content of a register plus an increment or a decrement.
As we’ll see later, the memory references of a process in a multitasking environment must somehow be bounded, so to protect from unwanted interferences memory areas like the unwritable parts of the process itself, or the memory areas containing the images of other processes, etc. This is usually accomplished in hardware by comparing the address of each memory reference produced by a process with the content of one or more bound registers or memory words, so that the processor traps an exception to block the process should an illegal address be generated.
Usually memory is allocated from a large pool of unused memory area called the heap. In C++, dynamic allocation/deallocation must be manually performed using commands like malloc, free, new and delete. Malloc allocates space of a given size and gives a pointer back to the programmer; the programmer then can do whatever he wants with it. The new command, on the other hand, allocates a specific object of a given