linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
  • Introduction
  • Lessons
  • How it works
  • Simulator
  • Knowledge base
  • Interview prep
Index
Categories
All entries
Footer
linuxlab-TutorialsPricingAboutPrivacy & cookies
Copyright © 2026 LinuxLab. All rights reserved.
home/linux/kb/Processes & resources/virtual-memory

kb/processes ── Processes & resources ── advanced

Virtual memory: virtual addresses, page tables

Each process sees its own 64-bit virtual address space. The MMU translates virtual addresses to physical ones through page tables. This is the basis of isolation and mmap.

view as markdownaka: vm, virtual-address-space, page-tables, mmu

Why it exists

Without virtual memory, every process would live in one flat memory space and corrupt its neighbors. Virtual addresses give you:

  1. Isolation: a process cannot reach into another process's memory
  2. The illusion of large memory: each process thinks it has 2^48 bytes; only what you actually use is mapped
  3. Lazy allocation: malloc(1GB) does not allocate physical memory until you write to it
  4. Shared mappings: one physical page can appear in the address spaces of several processes (shared libraries, mmap)
  5. Swap and page cache: a page can physically live on disk or in the cache

Page and page table

Memory is managed in pages (usually 4 KB, sometimes 2 MB / 1 GB, the "huge pages"). On every access the MMU does this:

  1. Takes the virtual address from the CPU
  2. Walks the page table of the process (a structure in physical memory)
  3. Finds the entry for that page, giving physical address + flags (rw/x, present)
  4. If the page is missing, a page fault fires and the kernel steps in

The TLB (Translation Lookaside Buffer) is a cache of recent translations inside the MMU itself. A TLB miss is expensive, so huge pages help memory-intensive workloads.

Kinds of page fault

  • Minor fault: the page is already in RAM (for example, in the page-cache), it just was not attached to this process yet. The kernel fixes up the page table, which is fast.
  • Major fault: the page has to be loaded from disk (swap or an mmap-ed file). This is real disk I/O, hundreds or thousands of times slower.
  • Segfault (SIGSEGV): access to an address that is not in the process map at all. The program crashes with a core dump.
bash
ps -o min_flt,maj_flt -p <pid>     # minor/major fault counters for the process
vmstat 1                            # columns si/so are swap-in/swap-out (major faults into swap)

A high maj_flt without swap means mmap-ed files with random access (databases, large datasets).

Process map: /proc/<pid>/maps

bash
cat /proc/self/maps | head
# 55ee87000000-55ee87004000 r--p 00000000 fc:01 1234567 /usr/bin/cat
# 55ee87004000-55ee87008000 r-xp 00004000 fc:01 1234567 /usr/bin/cat
# 55ee87008000-55ee8700a000 r--p 00008000 fc:01 1234567 /usr/bin/cat
# 7f1abcde0000-7f1abce00000 r--p 00000000 fc:01 7654321 /lib/x86_64.../libc.so.6
# ...

Columns: virtual range / perms (rwxp/s) / offset / device / inode / path. [heap], [stack], [vdso] are anonymous regions. This is EVERYTHING the process sees.

bash
pmap -x <pid>                      # a convenient view of the same data with sizes
cat /proc/<pid>/status | grep -E '^Vm'
# VmSize  - total VAS (virtual, not real memory)
# VmRSS   - Resident Set Size (actually in RAM right now)
# VmData  - heap + anonymous mmap-s
# VmSwap  - how much went to swap

RSS vs VSZ: the main misunderstanding

  • VSZ (virtual size) is how much the process reserved (lazy memory included)
  • RSS is how much is actually held in physical RAM right now

A Java program can show VSZ=10 GB, RSS=300 MB, and that is normal. The JVM allocates heap up front but physically uses little of it.

In containers the OOM killer (oom-killer) looks at RSS, not VSZ.

Memory commit and overcommit

When malloc() returns a pointer, there is no physical memory behind it yet. Linux can overcommit: hand out more virtual memory than physical+swap.

bash
cat /proc/sys/vm/overcommit_memory
# 0 - heuristic (default): usually grants; sometimes refuses
# 1 - always: grant to everyone; the OOM-killer sorts it out
# 2 - never: hard limit = swap + RAM*overcommit_ratio
cat /proc/sys/vm/overcommit_ratio   # usually 50, used when mode=2

Mode 2 (never) is for production databases and critical systems: better to get ENOMEM and handle it than to take an unexpected OOM-kill.

Huge pages

4 KB pages are too small when a process works with gigabytes, since the TLB overflows. Huge pages (2 MB and 1 GB) reduce TLB pressure:

bash
cat /proc/meminfo | grep Huge      # how many huge pages the system has
echo 1024 | sudo tee /proc/sys/vm/nr_hugepages   # reserve 1024 pages of 2MB each

Used in databases (Postgres huge_pages=on), the JVM (-XX:+UseLargePages), DPDK / kernel-bypass networking.

Transparent huge pages (THP): the kernel automatically merges 4KB pages into 2MB ones. Good for some workloads, harmful for others (jitter in databases):

bash
cat /sys/kernel/mm/transparent_hugepage/enabled
# always / madvise / never

Debugging

  • pmap -x <pid> is a map with sizes
  • smem shows RSS / PSS / USS per process (PSS = proportional, splits shared)
  • cat /proc/<pid>/smaps gives detailed info for each region
  • vmstat 1 shows pages in/out, swap, free
  • slabtop shows the kernel slab allocator (kernel structures)

§ команды

bash
cat /proc/$$/maps | head

Virtual memory map of the process: segments, libraries, heap, stack

bash
pmap -x <pid>

A convenient view of /proc/<pid>/maps with sizes and RSS per region

bash
cat /proc/<pid>/status | grep ^Vm

VmSize/VmRSS/VmSwap of the process; RSS shows the real consumption

bash
cat /proc/meminfo | grep -E 'MemTotal|MemAvailable|HugePages'

Total memory + available (counts page cache) + huge pages

bash
smem -tk -P python

RSS/PSS/USS for python processes; PSS is more accurate when there is shared memory

§ см. также

  • process-and-pidProcess and PIDA process is a running program with its own PID, memory, open descriptors, and UID. Every process forms a tree rooted at init (PID 1).
  • swapSwap: when RAM runs outSwap is disk space where the kernel pushes out rarely used memory pages when RAM is needed more. A partition or a file. Tuned by `vm.swappiness` (0-100).
  • page-cachePage cache: disk in memoryPage cache is RAM that holds file contents. Every filesystem read and write goes through it. In free it looks like used memory, but the cache is available.
  • mmapmmap: files and shared memory`mmap()` maps a file (or an anonymous region) into a process virtual address space. Reads and writes through the pointer become file operations. This is the basis of shared memory.
Footer
linuxlab-
Copyright © 2026 LinuxLab. All rights reserved.
Tutorials
Pricing
About
Privacy & cookies