Home/Learn/Operating Systems/Translation Lookaside Buffer (TLB)

Translation Lookaside Buffer (TLB)

Intermediate
Memory Management

The TLB is a small hardware cache of recent virtual-to-physical page translations that makes address translation nearly instantaneous on a hit, avoiding expensive page table walks.

Overview

Without caching, every memory access would require a page table walk: on x86-64 with 4-level paging, that is four additional memory accesses before reaching the actual data — a 5x overhead. The TLB solves this by caching the most recently used page table entries in a tiny, ultra-fast associative memory (typically 64–1024 entries) inside the CPU. A TLB hit translates the virtual address in ~1 CPU cycle. A TLB miss triggers a hardware page table walk (hardware TLB miss handler), which takes ~20–100 CPU cycles. TLB reach is entries × page size — for 64 entries and 4 KB pages that is only 256 KB. When a context switch occurs, the TLB must be flushed (or tagged with Address Space IDs — ASIDs — to avoid flushing). Huge pages (2 MB or 1 GB on x86) dramatically increase TLB reach and are used in performance-critical applications.

TLB Hit vs Miss and Effective Access Time

Effective memory access time (EAT) depends on TLB hit rate. With a 99% hit rate, a TLB hit costs ~1 cycle and a miss costs ~100 cycles (page table walk + memory access). EAT = hit_rate × hit_cost + (1 - hit_rate) × miss_cost. The TLB is why tight inner loops over arrays are so fast — the working set of pages fits in the TLB after the first pass.

Java — Effective Access Time with TLB hit/miss calculation
// Effective Access Time calculation
// Assumptions: TLB access = 1 ns, Memory access = 100 ns
// TLB hit rate = 99% (h = 0.99)

double tlbAccessTime  = 1.0;    // nanoseconds
double memAccessTime  = 100.0;  // nanoseconds
double hitRate        = 0.99;

// TLB hit path:  TLB lookup (1ns) + memory access (100ns) = 101 ns
// TLB miss path: TLB lookup (1ns) + page table walk (4×100ns) + memory access (100ns) = 502 ns
double hitCost  = tlbAccessTime + memAccessTime;          // 101 ns
double missCost = tlbAccessTime + 4 * memAccessTime + memAccessTime;  // 502 ns (4-level PT)

double eat = hitRate * hitCost + (1 - hitRate) * missCost;
System.out.printf("EAT = %.1f ns  (ideal no-TLB cost: %.0f ns)%n",
    eat, 4 * memAccessTime + memAccessTime);
// EAT ≈ 106 ns vs 500 ns without TLB → ~5x speedup at 99% hit rate

// TLB reach = TLB entries × page size
int tlbEntries = 64;
int pageSize   = 4096; // 4 KB
System.out.printf("TLB reach: %d KB%n", tlbEntries * pageSize / 1024);
// 256 KB — only covers 256 KB of working set with 4KB pages
// With 2MB huge pages: 64 × 2MB = 128 MB TLB reach!

TLB Flush on Context Switch and Huge Pages

When the OS context-switches between processes, each process has a different page table — TLB entries from the old process are invalid for the new one. A full TLB flush clears all entries, causing a surge of TLB misses for the first few microseconds. ASIDs (Address Space IDs) tag each TLB entry with the process ID, allowing multiple processes' translations to coexist in the TLB without flushing. Java applications benefit from huge pages (2 MB TLBentries) for large heaps, dramatically reducing TLB pressure.

Java — UseLargePages to reduce TLB pressure on large heaps
// Enabling huge pages for Java heap to reduce TLB pressure
// java -XX:+UseLargePages -XX:LargePageSizeInBytes=2m MyApp
//
// With 4 KB pages: a 4 GB heap = 1,048,576 pages
//   → TLB can only cache 64 of them → frequent misses in heap traversal
//
// With 2 MB huge pages: a 4 GB heap = 2,048 pages
//   → TLB can cache all of them with 64 entries → near-zero TLB misses!

// Checking if large pages are enabled
List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans();
pools.stream()
    .filter(p -> p.getName().contains("Heap"))
    .forEach(p -> System.out.printf("Pool: %-30s  used: %d MB%n",
        p.getName(), p.getUsage().getUsed() / 1_048_576));

// TLB miss symptoms in Java:
// - GC pauses are longer than expected (GC walks entire heap → TLB thrashing)
// - High sys CPU time relative to user CPU (kernel handling TLB miss interrupts)
// - Profiler shows high cost in memory barrier or fence instructions

Key Points to Remember

  • 1TLB is a hardware cache of recent page table entries — a hit translates addresses in ~1 CPU cycle.
  • 2TLB miss triggers a hardware page table walk — ~20-100 cycles; 4 memory reads on x86-64.
  • 3TLB reach = entries × page size; 64 entries × 4 KB = 256 KB — small for multi-GB heaps.
  • 4Context switch without ASIDs requires full TLB flush — causes TLB cold-start miss surge.
  • 5Huge pages (2 MB) increase TLB reach 512x — critical for GC performance on large Java heaps.
  • 6EAT = hit_rate × (tlb_time + mem_time) + miss_rate × (tlb_time + page_walk + mem_time).

Interview Questions

Sign in to ask Aria
1

What is the TLB and why is it needed?

EasyAmazon
2

Calculate Effective Access Time given TLB hit rate, TLB latency, and memory latency.

MediumMicrosoft
3

Why does a context switch hurt performance beyond just saving and restoring registers?

HardGoogle
4

How do huge pages improve TLB hit rate for a Java application with a 16 GB heap?

HardUber

Ask Aria about Translation Lookaside Buffer (TLB)

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…