How Firefox's "Minimize Memory Usage" Triggers the GC

Clicking the "Minimize memory usage" button in Firefox's about:memory page forces the browser to immediately reclaim as much system RAM as possible. This article provides a direct breakdown of the internal actions triggered by this button, explaining how it broadcasts a global low-memory notification, initiates multiple rounds of aggressive garbage and cycle collection, compacts the memory heap, discards compiled code, and purges internal browser caches to return unused memory back to the operating system.

1. The Global Memory-Pressure Event

When you click "Minimize memory usage", Firefox does not just run a standard cleanup. Instead, it broadcasts a global internal notification called memory-pressure with the specific parameter heap-minimize across the parent process and all content processes. Every major subsystem in the browser listens for this specific event and reacts immediately.

2. Full, Non-Incremental Shrinking Garbage Collection

Inside SpiderMonkey (Firefox's JavaScript engine), the garbage collector (GC) usually runs incrementally in small slices to avoid freezing the browser. The heap-minimize trigger overrides this behavior and forces a full, non-incremental Shrinking GC across all memory zones simultaneously.

A Shrinking GC performs three aggressive actions:

  • Mark and Sweep: It pauses JavaScript execution to scan the entire memory heap, identifying and deleting all unreachable JavaScript objects.
  • Heap Compaction: Standard garbage collection leaves gaps of free memory between live objects (fragmentation). A shrinking GC physically relocates live objects in memory, packing them tightly together into fewer memory arenas.
  • Decommitting Memory: Once the live objects are compacted, the newly emptied memory arenas and chunks are actively decommitted. This means Firefox uses operating system calls to hand the physical RAM directly back to the OS, rather than holding onto it for future browser use.

3. Flushing JIT Code

As part of the shrinking GC, SpiderMonkey purges nearly all Just-In-Time (JIT) compiled machine code. Firefox compiles frequently used JavaScript into native machine code for speed, which consumes a significant amount of memory. The GC deletes this compiled code and falls back to the baseline interpreter. If a webpage still needs the code, it will simply recompile it later.

4. Triggering the Cycle Collector

JavaScript objects are managed by the Garbage Collector, while C++ and DOM (Document Object Model) objects are managed by Reference Counting. Reference counting cannot automatically free "cycles" (where Object A points to Object B, and Object B points back to Object A).

To solve this, the button triggers Firefox's Cycle Collector (CC) immediately after the JS GC finishes. The Cycle Collector analyzes the web of C++ and DOM references, identifies isolated loops of dead objects, breaks the links, and frees the memory.

5. The Multi-Pass Loop

A single pass of the Garbage Collector and Cycle Collector is often not enough. A dead JavaScript object might be keeping a C++ DOM element alive, which in turn is keeping another JavaScript object alive.

To untangle these cross-language references, the "Minimize memory usage" action runs the Shrinking GC and the Cycle Collector in a sequential loop—typically three times in a row.

  1. Pass 1 frees unreferenced JS objects, which exposes dead C++ cycles.
  2. The CC deletes those C++ cycles, which exposes newly unreferenced JS objects.
  3. Pass 2 and Pass 3 clean up the remaining fallout until no more memory can be freed.

6. Purging Browser Caches

Before and during the GC/CC passes, the memory-pressure notification forces other browser subsystems to dump their temporary data. This includes:

  • Decoded image caches (forcing images to be re-decoded if scrolled back into view).
  • The Back/Forward cache (bfcache), which keeps previously visited pages in memory for instant navigation.
  • Font, style, and network caches.

By emptying these caches first, thousands of underlying DOM and JavaScript objects lose their active references, making them immediately eligible to be swept away and decommitted by the Garbage Collector during its shrinking passes.