TDC 311 Memory Management Why Do We Need Memory Management? Protection - to protect one process from another; the OS from processes; resident libraries from processes. Sharing code - what if two different processes want to share a piece of code? Logical organization - allows for multiple, independent modules to reside in memory at the same time. Virtual memory - processes are bigger than main memory. Memory management allows a large process to partially occupy main memory. Historical Perspective Bare Machine - no memory management. User has entire machine. Resident Monitor - memory divided into 2 sections monitor and user. Protection hardware consists of one fence register. User memory does not start at location 0. OS starts at 0. User starts at location n. Are programs compiled/assembled at location n? Probably not, so need relocation. Static relocation - IBM 370 style. Dynamic relocation - CDC 6600 style with relocation register. Logical address space : What the user sees : 0 to max. Physical address space : What the OS uses: R+0 to R+max for fence register value R. Historical Perspective Continued Swapping - memory still divided into monitor space and user space, but you may have more than one job/process, so swap one in, execute it, swap it out, swap next one, etc. Overlapped swapping - memory divided into monitor, buffer1, buffer2, and user space. Keep two jobs in buffer spaces and swap them in and out of user space as needed. Multiple partitions - memory is divided into regions, or partitions. For a job to execute, it is loaded into a free partition. When done, the job is removed and the partition is marked free. Can have fixed (static) sized partitions (MFT) and variable (dynamic) sized partitions (MVT) (IBM OS/360). MFT Multiprogramming with Fixed-Sized Tasks Problems: Asking for more memory Internal fragmentation MVT Multiprogramming with Variable-Sized Tasks No fixed sized partitions. Fit job wherever it will fit. Best fit? First fit? Worst fit? Problems: Fragmentation Garbage collection (compaction). Simple Paging Divide memory into fixed sized frames Divide user process into fixed sized pages Take a page of user program and plug into empty frame Each job has its own page table No external fragmentation, only internal fragmentation On average, ½ of a frame will be wasted Shared pages - possible to share pages (like editor, compiler, database code) if code is reentrant (does not modify itself). Protection - can add read only / read write / execute bits to each page in the page table. Simple Segmentation Like paging, but user job not broken into fixed sized pages (physical division) but left as procedures / functions / data sets Protection - can now place access bits on entire segment. A code segment can be accessed by many users. A data segment can be accessed by only one user. Put an array in a segment by itself and the hardware will check the array bounds automatically! Sharing - same as with paging Virtual Memory Why load the entire program into memory at the start? Just load the necessary routines / modules. Why? Error routines are seldom called. Don’t always need entire array, list or table. Certain sections of code may be rarely used. Resident set - portion of user process that is currently in main memory. Advantages of virtual memory - may have more processes in memory since only part of each process is resident. It is possible for a process to be larger than main memory. Virtual Memory Continued Disadvantages - if part of a process is not in memory, process is moved to blocked state, disk I/O reads in necessary piece of code, process is moved to Ready state, process resumes execution Thrashing - removing a piece to satisfy some other process, but then needing that piece next. Demand Paging Page table for each process must also include 1 bit for each page – this bit tells if page is in memory, or resident Also, one Modify bit for each page - tells if the page has been modified What if page is not resident? Take page number, look in page table. Is the page resident? If yes, get frame number. If no, page fault. Find a free frame. No free frame? Call replacement algorithm. Load desired page from disk into memory. When disk read completed, update page table. Restart instruction. Paging Issues Page size - the smaller the page, the less internal fragmentation, but the bigger the page table. If a page is 512 bytes in size (29) and we are using a memory space 231, we will need 222 page table entries per process! How do you handle such a large page table? Keep only part of the page table resident, or use an inverted page table. Typical page sizes: IBM 370: 2048 / 4096;VAX: 512; INTEL 486: 4096; Motorola 68040: 4096. The paging process can be time intensive. Make sure the paging process is fast and doesn’t occur constantly. Pure demand paging vs. prepaging Page Replacement Algorithms If you need to bring a page in, but there are no available frames, you have to remove a page and put it back to disk. Who do you remove? Let’s say we are given the following page reference string: 70120304230321201701 and 3 frames of memory FIFO (first in first out): LRU (least recently used): Optimal (theoretical): Other Issues How many pages at one time do you give to each process (resident set size)? Can the resident set size change as the process’s demands grow and shrink? When you take a page out to make room for another page, check its Modify bit. If it has not been set, the page has not been modified (is not dirty) and there is no need to write the page back to disk. There is also demand segmentation. Example – Windows NT Page size = 4096 bytes. Segmentation and paging are optional and in combinations. With unsegmented memory, user’s virtual space is 232 = 4 Gb. With segmentation, there is a 16-bit segment reference (of which 2 bits are used for protection) and a 32 bit offset, for 246 = 64Tb ! Paging is done via 2 levels - first level is a page directory containing 1024 entries. Each entry is a page table with 1024 entries. Each entry is 4 Kb. Example – Linux Linux uses either 3-level paging or the more recent 4level paging From IBM’s Explore the Linux Memory Model (3-level): Example – Linux In 64-bit processors: The remaining 30 bits are divided into 21 MSBs are unused 13 LSBs are represented by page offset 10 bits for Page Table 10 bits for Page Global Directory 10 bits for Page Middle Directory Thus, 43 bits are used for addressing. This yields 243 bytes of available virtual memory space