Labs ICT
Pro Login

Memory Management Overview

How the OS allocates and protects RAM.

Why Memory Management Matters

Your computer has a limited amount of RAM — maybe 8GB, 16GB, or 32GB. But you might have dozens of processes running, each needing memory for their code, data, and variables. Without careful management, processes would step on each other's memory, causing crashes and data corruption.

The operating system's memory manager is like a librarian in a busy library. It decides who gets which shelf, makes sure nobody takes someone else's books, and reorganizes the shelves when someone leaves. The goal is to maximize the use of available memory while keeping every process safely isolated.

How Memory is Organized

When a computer boots, the OS loads itself into a portion of memory and leaves the rest available for processes. The memory is typically divided into:

  • Kernel Space — Reserved for the operating system itself. User processes can't access this area directly.
  • User Space — Where application processes run. Each process gets its own chunk of user space.

The OS uses memory allocation to assign portions of RAM to processes. When a process needs memory (for example, when it creates a variable or loads a file), the OS finds a free block and assigns it. When the process finishes, that memory is reclaimed.


  Memory Layout of a Running Process:

  High Address ┌─────────────────────┐
               │     Kernel Space    │  ← OS code, data, stack
               │     (protected)     │     (not accessible by user)
               ├─────────────────────┤
               │        Stack        │  ← Local variables, function calls
               │          ↓          │     (grows downward)
               ├─────────────────────┤
               │                     │
               │        Free         │  ← Unused memory
               │                     │
               ├─────────────────────┤
               │          ↑          │
               │        Heap         │  ← Dynamic allocation (malloc)
               │                     │     (grows upward)
               ├─────────────────────┤
               │   BSS (uninitialized)│  ← Global variables (zero-init)
               ├─────────────────────┤
               │   Data (initialized)│  ← Global variables with values
               ├─────────────────────┤
               │       Text          │  ← Program code (read-only)
  Low Address   └─────────────────────┘

Contiguous Allocation

The simplest approach is contiguous allocation — each process gets a single, continuous block of memory. The OS tracks which blocks are free and which are occupied using a table or bitmap.

This approach has a problem: external fragmentation. As processes are created and destroyed, the free memory becomes scattered in small chunks between occupied blocks. Even if there's enough total free memory, it might not be in one contiguous block, so a new process can't be loaded.

It's like having a bookshelf with 10 empty slots spread across five shelves — there's room for a 10-book series, but not if it needs all 10 slots on the same shelf.

Memory Protection

One of the most critical jobs of the memory manager is protection. Process A should never be able to read or write to Process B's memory. If it could, a bug in one program could corrupt another program's data — or worse, the operating system's data.

The OS uses hardware support to enforce protection. Each process has base and limit registers that define the boundaries of its memory space. The CPU checks every memory access — if it falls outside the process's boundaries, the access is rejected and the process is terminated.

This hardware-enforced isolation is what makes modern multitasking safe. Your browser can't accidentally overwrite your music player's data, and neither can overwrite the kernel's data.