zhuang@linux:~/blog/process-memory-layout/$ cat
Process Memory Layout
The term process memory layout usually refers to the layout of a process’s virtual address space, not the direct layout of physical memory.
A typical layout looks roughly like this:
text
High addresses
┌─────────────────┐
│ Kernel space │
├─────────────────┤
│ Stack │ Local variables and function frames
│ ↓ │
│ │
│ ↑ │
│ Heap │ malloc / free
├─────────────────┤
│ BSS │ Uninitialized global/static variables
│ Data │ Initialized global/static variables
│ Text │ Program code and read-only constants
└─────────────────┘
Low addressesThis is the virtual address view that the operating system gives to each process. When the CPU accesses a variable, it uses a virtual address. The memory management unit (MMU) translates that address into a physical address through page tables:
text
Virtual address → MMU / page table → physical memory pageTherefore:
- Memory that is contiguous in virtual address space may not be contiguous in physical memory.
- The relative positions of the stack and heap do not mean they have the same arrangement in physical memory.
- Some virtual pages may not have physical memory assigned yet.
- Some pages may be moved to swap space.
- Shared libraries and shared memory can map different virtual addresses to the same physical page.
- Native memory allocators such as
mallocreturn virtual addresses; the operating system usually provides the underlying physical pages on demand.
The idea that “the stack grows downward and the heap grows upward” describes a common implementation, not a universal rule. The actual layout depends on the operating system, CPU architecture, linker, language runtime, and security features such as ASLR.
zhuang@linux:~/blog/process-memory-layout/$ comments