Stack vs heap
Programs use two primary memory regions with fundamentally different allocation strategies:- Stack
- Heap
Stack memory
The stack is a contiguous, automatically managed memory region that grows and shrinks as functions are called and return.Characteristics:- LIFO (Last In, First Out) allocation order
- Automatic management - no manual allocation/deallocation
- Fast allocation - just increment/decrement stack pointer
- Limited size - typically 1-8 MB per thread
- Predictable lifetime - variables freed when function returns
- Local variables
- Function parameters
- Return addresses
- Saved registers
Virtual memory basics
Virtual memory creates an abstraction layer between physical RAM and the memory addresses used by programs.Key concepts
1
Address translation
Each process has its own virtual address space. The memory management unit (MMU) translates virtual addresses to physical addresses using page tables.
2
Paging
Memory is divided into fixed-size pages (typically 4 KB). The OS can map any virtual page to any physical page, enabling:
- Process isolation - processes cannot access each other’s memory
- Demand paging - load pages from disk only when needed
- Memory overcommitment - allocate more virtual memory than physical RAM
3
Page faults
When a process accesses a virtual address not currently in physical memory, a page fault occurs. The OS handles this by:
- Pausing the process
- Loading the required page from disk
- Updating page tables
- Resuming execution
Virtual memory allows running programs larger than available RAM by swapping pages between memory and disk. However, excessive paging (thrashing) severely degrades performance.
Benefits of virtual memory
- Memory protection - each process has isolated address space
- Simplified memory management - programs see contiguous memory
- Efficient memory use - share common code/libraries between processes
- Larger address space - programs can use more memory than physically available
Memory layout
A running process’s virtual memory is organized into distinct segments:Segment descriptions
Text segment
Text segment
Contains the executable program code (machine instructions).
- Read-only and executable - prevents code modification
- Shareable - multiple processes can share same code
- Fixed size - determined at compile time
Data segment
Data segment
Stores initialized global and static variables.
- Read-write - variables can be modified
- Fixed size - known at compile time
- Initialized - contains specific values from source code
BSS segment
BSS segment
Contains uninitialized global and static variables (Block Started by Symbol).
- Zero-initialized - all bytes set to 0 at program start
- Not stored in executable - saves disk space
- Fixed size - known at compile time
Heap segment
Heap segment
Dynamic memory allocated at runtime.
- Grows upward - toward higher addresses
- Managed by allocator - malloc/free in C, new/delete in C++
- Flexible size - grows as needed (up to limits)
Stack segment
Stack segment
Function call frames and local variables.
- Grows downward - toward lower addresses
- Automatically managed - push/pop on call/return
- Limited size - typically 1-8 MB
Pointers and memory alignment
Pointers
Pointers store memory addresses, enabling direct memory manipulation:Simple memory alignment
CPUs access memory most efficiently when data is aligned to its natural boundaries:- Alignment requirement - address must be a multiple of data size
- Performance impact - unaligned access may require multiple memory operations
- Padding - compilers insert padding bytes to maintain alignment
System calls overview
Programs interact with the operating system through system calls to perform privileged operations:- Process control - fork, exec, exit, wait
- File operations - open, read, write, close
- Memory management - brk, mmap, munmap
- Communication - pipe, socket, send, receive
System calls involve a context switch from user mode to kernel mode, which is relatively expensive. Minimize system calls in performance-critical code.