Memory and virtual memory
Address spaces, the stack and heap, paging and page faults, and how swapping and the OOM killer decide what survives.
Inside a virtual address space
Every process believes it owns a contiguous range of memory. The MMU translates each access through page tables to a physical frame, so two processes can use the same virtual address and never collide.
| Region | Holds | Grows |
|---|---|---|
| Text | Machine code, read-only | Fixed at load |
| Data / BSS | Initialised and zero-initialised globals | Fixed at load |
| Heap | Allocations from malloc / new | Upward |
| Stack | Frames, locals, return addresses | Downward |
| Memory-mapped files | Libraries, mmap regions | On demand |
free -h # total, used, buff/cache, available
cat /proc/meminfo | head -5
vmstat 1 5 # watch si/so: swap-in and swap-out per second
ulimit -a # per-process limits, including stack size (Kb)Paging, faults and the working set
Memory is managed in fixed-size pages (typically 4 KB). A reference to a page that is not resident triggers a page fault: a minor fault if the page is already in memory or can be recreated, a major fault if it must be read from disk.
# faults per second, split minor/major (-s summary)
/usr/bin/time -v ./myprogram 2>&1 | grep -E 'Maximum resident|page faults'- The CPU raises a fault for the missing page and the thread blocks.
- The kernel finds or creates the page: from the page cache, a file, or the swap device.
- Page tables are updated and the instruction is retried — the program never notices.
- If no free frame exists, the page replacement policy picks a victim (LRU approximations) and evicts it.
⚠️
Thrashing is worse than running out of memory: the system spends its time evicting and re-reading pages instead of doing work. If
vmstat shows sustained si/so activity, add memory or reduce the working set — do not just increase swap.Fragmentation and the OOM killer
- Internal fragmentation wastes the tail of a fixed-size block; external fragmentation leaves free space that is too scattered to use.
- Linux overcommits memory by default, so a large
malloccan succeed and the process is killed only when a page is actually touched. - The
OOM killerscores processes by memory use andoom_score_adj, then kills the worst offender — often not the one that caused the spike. - Memory-mapped files count towards
RSSwhile resident but can be evicted for free, which is whyfreealso reportsbuff/cache. - A container limit is enforced as an OOM condition; exceeding it terminates the container rather than slowing it down.
# who is actually using memory, and how much is reclaimable
ps -eo pid,rss,vsz,comm --sort=-rss | head -10
# is a process leaking, or just caching? watch RSS over time
while true; do ps -o rss= -p 1234; sleep 5; doneFAQ
Why is my process killed with no stack trace?
Almost always the OOM killer. Check
dmesg for an out-of-memory message naming the process, then look at peak RSS, container limits, and any unbounded cache.Does a memory leak always mean lost memory?
No — an ever-growing cache is indistinguishable from a leak in RSS terms. If freeing the cache returns memory and performance stays acceptable, the growth may be intentional.
Related
Processes and threads Files, permissions and I/O
Last refreshed 2026-09-18.