Introduction
Understanding how system memory is organized in UNIX is essential for understanding process management. UNIX divides memory into kernel space and user space, and each process has a well-defined memory layout within user space.
Kernel Space vs User Space
| Aspect | Kernel Space | User Space |
|---|---|---|
| Purpose | OS kernel code and data | User programs and data |
| Access | Only kernel mode (ring 0) | User mode (ring 3) |
| Protection | Fully privileged | Restricted access |
| Address Range | Upper portion of virtual address space | Lower portion of virtual address space |
| Contents | Kernel code, process table, buffer cache, device drivers | Program code, data, stack, heap |
Process Memory Layout
Each process in UNIX has the following memory segments:
High Address
┌──────────────────────────┐
│ Kernel Space │ (Not accessible by process)
├──────────────────────────┤
│ Stack │ ← Grows downward (↓)
│ (Local vars, args, │
│ return addresses) │
│ ↓ │
│ │
│ (Free / Unmapped) │
│ │
│ ↑ │
│ Heap │ ← Grows upward (↑)
│ (malloc, dynamic alloc)│
├──────────────────────────┤
│ BSS (Uninitialized │
│ Data Segment) │
│ (Zeroed globals) │
├──────────────────────────┤
│ Data Segment │
│ (Initialized globals │
│ and static vars) │
├──────────────────────────┤
│ Text Segment │
│ (Program code / │
│ instructions) │
│ Read-only, Shareable │
└──────────────────────────┘
Low Address
Detailed Segment Descriptions
1. Text Segment (Code Segment):
- Contains the compiled machine instructions of the program.
- Read-only — prevents accidental or malicious modification of code.
- Shareable — if multiple processes run the same program, they share one copy of the text segment in memory.
- Size is fixed at compile time.
2. Data Segment (Initialized Data):
- Contains global and static variables that have been explicitly initialized.
- Example:
int count = 10; - Read-write.
3. BSS Segment (Block Started by Symbol / Uninitialized Data):
- Contains global and static variables that are declared but not initialized.
- Example:
int total;— automatically initialized to 0. - The BSS segment does NOT occupy space in the executable file (only size info is stored); memory is allocated and zeroed at load time.
4. Heap:
- Used for dynamic memory allocation at runtime.
- Grows upward (toward higher addresses) using
malloc(),calloc(),realloc(). - Freed using
free(). - The
brk()/sbrk()system calls adjust the heap boundary.
5. Stack:
- Used for function calls — stores local variables, function arguments, return addresses, and saved registers.
- Grows downward (toward lower addresses).
- Each function call creates a new stack frame.
- Stack overflow occurs if the stack grows too large (e.g., infinite recursion).
Memory Management Techniques
1. Swapping:
- The swapper (process 0) moves entire processes between memory and disk (swap space).
- When memory is full, idle or low-priority processes are swapped out.
- When they need to run, they are swapped back in.
2. Demand Paging:
- Instead of swapping entire processes, only individual pages (fixed-size memory blocks, typically 4 KB) are moved to/from disk.
- Pages are loaded into memory on demand — only when accessed (page fault triggers loading).
- More efficient than swapping for large processes.
3. Virtual Memory:
- Each process has its own virtual address space independent of physical memory.
- The Memory Management Unit (MMU) translates virtual addresses to physical addresses using page tables.
- Allows processes to use more memory than physically available.
Summary
- UNIX divides memory into kernel space (privileged) and user space (restricted).
- Each process has text, data, BSS, heap, and stack segments.
- Stack grows downward; heap grows upward.
- Swapping moves entire processes; demand paging moves individual pages.
- Virtual memory allows each process to have its own address space.