SeriesOperating Systems8 / 16

Memory Management

Module 8 of CS 6200 - Graduate Introduction to Operating Systems @ Georgia Tech.

Overview#

Memory Management is the process of controlling and coordinating a computer’s main memory (RAM), with specific regards to allocation / deallocation and use optimization.

Recall that each process has its own virtual address space, which maps memory pages (virtual memory) to page frames (physical memory). Alternatively, an OS might support segment-based memory management, where segments are more flexibly-defined regions of virtual memory.

page-based-memory

Memory Structures#

Hardware#

What sort of hardware support does a computing system provide in terms of memory management? The Memory Management Unit (MMU) is a physical subdivision of the CPU, and has a few key responsibilities:

Other hardware components provide support in indirect ways:

Page Tables#

Definition#

Pages (as opposed to segments) are the more popular method for memory management. A Page Table defines the mapping between any virtual page and a page frame in DRAM. Page tables are specific to processes + stored in RAM - the process control block (PCB) contains a pointer to the relevant page table.

Pages have expected size (specified by page category), which facilitates an easier virtual-to-physical translation process. For example, pages and page frames may be uniquely identified by their starting memory address, as opposed to keeping track of the start and end addresses. This implies that the contents of an individual page frame (in physical memory) must be contiguous.

page-table
Use within Translation#

How does the MMU perform translation between a virtual page and physical page frame?

  1. MMU is queried with a virtual address of interest.
  2. MMU splits virtual address into…
    • Virtual Page Number (VPN): index in page table corresponding to virtual page.
    • Offset: number of positions from the starting memory address of virtual page.
  3. MMU indexes into page table using VPN. VPN is associated with Physical Frame Number (PFN), which is the starting memory address corresponding to the physical page frame.
  4. MMU concatenates offset with PFN to yield final physical address of interest.
Managing Page Table Entries#

What happens when a process requests memory via allocation (such as with malloc in C or new in C++)?

  1. First, the allocation is performed in virtual memory. In practice, this means we assign the starting virtual memory address of the allocated virtual memory to a pointer.
int size = 10;
int* arr = new int[size];
  1. When the process attempts to access this memory for the first time, the OS will select a page frame to map to, and define the appropriate mapping in the process’ page table.
arr[5] = 3;
  1. When the process deallocates this memory, the OS removes the associated entry from the page table and marks the physical page frame as free for use. This might not happen immediately depending on current system memory demands.
delete[] arr;

Every page table entry is uniquely identified by VPN, and typically contains the following information:

page-table-entry

The MMU uses page table entries to perform address translation, and also establish validity of access. If the MMU determines that the requesting process cannot access its requested memory location, it will generate a page fault. This involves passing control to the OS to call the appropriate page fault handler. For example…

Multi-Level Page Tables#

Page tables aren’t typically defined in a flat manner. Instead, we use a hierarchical structure to enable more efficient indexing and memory usage. For example, a two-layer page table dedicates its first layer to indexing pages of page tables, and its second level to indexing page entries (mapping virtual pages to page frames).

multi-level-paging

We can extend this principle to apply to n-level page tables. The primary downside of using deeper multi-level page tables is the amount of memory accesses (and corresponding overhead) associated with a single translation.

Translation Lookaside Buffer (TLB)#

The translation lookaside buffer (TLB) is used to increase translation speed, especially in the context of multi-level page tables. Without the TLB, we have overhead proportional to page table depth:

translation-lookaside-buffer

The TLB is a cache within the MMU which maintains valid virtual-to-physical address mappings. Even a small number of cached translations can result in high TLB hit rate, and thus solid performance gains. Obviously, we should not maintain all possible mappings in the TLB due to 1) infeasibility in terms of cache size, and 2) degrading our TLB to simply be a single-level page table!

Mechanisms for Memory Management#

Memory Allocation#

Memory Allocation refers to the process of reserving main memory (RAM) for a virtual address. In practice, this means defining a valid mapping between the requested virtual page and a free-for-use page frame. The memory allocator determines virtual-to-physical address mapping as part of memory allocation.

Kernel-level allocators allocate memory for the kernel - this is typically done for kernel state and kernel process management. These allocators are also responsible for keeping track of free physical memory in the system.

User-level allocators allocate memory for dynamic process state (ex: heap region of a program’s memory). This is accomplished via the malloc / free methods in C, and the new / delete methods in C++.

Challenges#

One common challenge of memory allocation is external fragmentation, which refers to the case where multiple interleafed malloc and free operations result in fragmented physical memory. External fragmentation can occur in the context of both virtual and physical memory - consider the following examples.

In either case, allocation algorithms (implemented at the allocator level) are responsible for limiting instances of external fragmentation, as well as reorganizing free memory regions into contiguous blocks at various intervals.

Linux Allocators#

The Linux kernel relies on two basic allocation algorithms:

linux-buddy-allocator
linux-slab-allocator

Linux uses a combination of buddy and slab allocators, since the use of buddy alone would result in substantial internal memory fragmentation (e.g., in the case where requested memory size is nowhere close to a power of 2).

Demand Paging + Page Replacement#

Physical main memory (RAM) is much smaller than virtual memory across all processes. To support this scenario, the OS does not keep all virtual memory pages in RAM at any given time. Instead, the page frame corresponding to a particular virtual page can be saved / restored relative to secondary storage locations (e.g., disk). Demand Paging refers to swapping pages between main memory and a swap partition as needed.

For example, consider the case where a process attempts to access memory that is currently “paged out” onto disk. The OS must return the missing page back to physical memory, then restart the access instruction.

demand-paging

Demand paging typically defines a different page address (depending on the current state of free main memory) for the same page when swapped back into RAM, relative to its original page address when the memory was first allocated. If the page should have constant page address / be present in RAM at all times, we must specify that the page should be pinned - this simply means swapping for the page is disabled. This is useful when the CPU is interacting with devices that directly interact with RAM.

Our current framework still leaves some uncertainties:


(all images obtained from Georgia Tech GIOS course materials)

License

CC BY-NC-SA 4.0 This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Related Posts