Every running Linux process has its own virtual memory layout.
Inside that layout are several important regions. Three of the most important are:
Stack → automatic function-call memory
Heap → dynamically allocated memory
mmap → mapped memory regions
A process does not simply have “memory.” It has a structured virtual address
space, divided into regions with different purposes.
High-Level Memory Layout
A simplified Linux process layout looks something like this:
High Memory
────────────────────────────────
Stack
↓ grows downward
Memory mappings
shared libraries
files mapped with mmap()
anonymous mmap regions
Heap
↑ grows upward
Program data
global variables
static variables
Program text
machine code
────────────────────────────────
Low Memory
The exact layout depends on architecture, kernel settings, address-space
randomization, executable type, shared libraries, and runtime behavior.
The diagram is conceptual. Linux may place regions differently, but the
core idea remains: a process has separate regions for code, data, stack,
heap, and mappings.
The Stack
The stack is used for function calls and short-lived automatic storage.
When a function is called, Linux and the CPU cooperate with the program’s
calling convention to build a stack frame.
Stack Usually Contains
Function call information
Return addresses
Local variables
Saved registers
Function arguments, depending on architecture and calling convention
Simple Stack Example
#include <stdio.h>
void greet() {
int number = 42;
printf("Number: %d\n", number);
}
int main() {
greet();
return 0;
}
The variable number is an automatic local variable. It normally
lives in the stack frame for greet().
Stack Growth
On many common systems, the stack grows downward, from higher virtual
addresses toward lower virtual addresses.
If a program uses too much stack memory, it can hit the stack limit and
crash with a stack overflow.
The Heap
The heap is used for memory that is requested while the program is running.
In C, this commonly happens through malloc(), calloc(),
realloc(), and free().
Simple Heap Example
#include <stdio.h>
#include <stdlib.h>
int main() {
int *numbers = malloc(10 * sizeof(int));
if (numbers == NULL) {
return 1;
}
numbers[0] = 42;
printf("%d\n", numbers[0]);
free(numbers);
return 0;
}
The pointer variable numbers may live on the stack, but the
memory it points to lives in dynamically allocated memory.
Stack memory is automatically managed by function calls.
Heap memory is explicitly requested and released by the program.
Heap Growth
Traditionally, the heap grows upward, toward higher virtual addresses.
Modern allocators may use both the traditional heap and mmap()
internally, depending on allocation size and strategy.
mmap
mmap() creates a mapping in a process’s virtual address space.
A mapping can connect part of a process’s address space to:
a file on disk
shared libraries
anonymous memory not backed by a normal file
shared memory between processes
large memory allocations created by the memory allocator
After this call, the process can access the file through memory addresses
instead of repeatedly calling read().
Anonymous Mapping
Anonymous mappings are memory regions not directly backed by a named file.
Programs and memory allocators often use anonymous mappings for large
memory areas.
Process Virtual Address Space
+------------------------------+
| Stack |
| function calls, local vars |
+------------------------------+
| mmap regions |
| libraries, files, anon maps |
+------------------------------+
| Heap |
| malloc/free dynamic memory |
+------------------------------+
| Data |
| globals, statics |
+------------------------------+
| Text |
| program machine code |
+------------------------------+
These are all virtual memory regions. They appear to the process as memory
addresses, but the kernel and CPU translate those virtual addresses into
physical memory when needed.
Connection to Page Faults
Stack, heap, and mmap regions do not always correspond to physical RAM
immediately.
A process may have a valid virtual memory region, but the physical page may
not be present yet.
When a program touches a valid virtual address whose physical page is not
currently ready, the CPU triggers a page fault and the kernel responds.
That is why Page Faults naturally come next.
Common Commands to Observe Memory
View a Process Memory Map
cat /proc/<PID>/maps
Example
cat /proc/$$/maps
The $$ variable expands to the current shell’s process ID.
Use pmap
pmap <PID>
Memory Summary
cat /proc/<PID>/status
Quick Comparison
Region Main Purpose Managed By
──────── ────────────────────────────────── ─────────────────
Stack function calls, local variables compiler/runtime/CPU
Heap dynamic allocation malloc/free allocator
mmap mapped files, libraries, anon maps kernel + program request
Conceptual Summary
The stack, heap, and mmap regions are major parts of a process’s virtual
memory layout.
The stack handles function-call memory.
The heap handles dynamic allocation.
mmap creates flexible mapped regions for files, libraries, shared memory,
and large anonymous allocations.
Visual Model
See the complete Stack, Heap, MMap path as a step-by-step diagram.