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
Address translation
Each process has its own virtual address space. The memory management unit (MMU) translates virtual addresses to physical addresses using page tables.
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
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.