V8 details Oilpan, its C++ garbage collector for Chromium
V8 has published the first post in a new blog series about Oilpan, the garbage collector Chromium's Blink rendering engine uses to manage C++ memory. Blink is a large C++ codebase, and its DOM objects are heavily tangled with JavaScript objects that V8 manages, so the Chromium team switched to Oilpan and connected it to V8 through cross-component tracing that treats the mixed C++/JavaScript object graph as a single heap.
Oilpan is a Mark-Sweep collector. Marking scans the heap from roots (registers, the native execution stack, and other globals) to find live objects; C++ types describe their own outgoing pointers by inheriting from GarbageCollected
The post's main focus is sweeping, the phase that reclaims memory from objects found dead during marking. Because C++ requires destructors to run before memory is freed, non-trivial destructors are implemented as finalizers, and since the sweeper does not iterate in construction order, finalizers are barred from touching other on-heap objects, a rule enforced by a Clang plugin. For rarer cases that must access the heap before destruction, Oilpan offers pre-finalization callbacks, but these carry more overhead per collection cycle and are used sparingly in Blink.
Sweeping itself evolved in three stages. It began as stop-the-world sweeping, running inside the garbage collection pause and stalling the application; because that can cause visible latency, it moved to incremental sweeping, splitting the work into additional main-thread tasks that run in idle time between already-swept and to-be-swept memory pages. As object graphs grew, incremental sweeping still hurt application performance, so Oilpan added concurrent sweeping on background threads. Two invariants keep this safe: the sweeper only touches memory already known to be dead, and the application only allocates from pages already fully swept, so the two never contend for the same object. Because finalizers must still run on the main thread, the concurrent sweeper pushes any object with a destructor onto a finalization queue processed later in a main-thread finalization phase, and only adds an object's memory to the free list after its finalizer, if any, has run.
Background sweeping has already shipped in Chrome M78. V8's real-world benchmarking framework shows it cuts main-thread sweeping time by 25 to 50 percent, 42% on average, across a set of measured line items; the post says the Chromium team is now working to reduce finalizer overhead for heavily instantiated Blink object types, which will let sweeping speed up further automatically as finalizers disappear. Looking ahead, the post states that Oilpan, currently implemented inside Blink, is moving into V8 itself as a standalone garbage collection library, with the stated goal of making C++ garbage collection available to other V8 embedders and to C++ developers more broadly.
Key facts
- Oilpan is Chromium's C++ garbage collector, connected to V8 via cross-component tracing so the DOM's tangled C++/JavaScript object graph is treated as one heap.
- Concurrent background-thread sweeping cuts main-thread sweeping time by 25 to 50 percent, 42% on average, per V8's real-world benchmarking framework.
- Background sweeping has already shipped in Chrome M78.
- C++ finalizers (non-trivial destructors) must run on the main thread; the concurrent sweeper defers them to a finalization queue rather than running them on the background thread.
- Oilpan is moving from being Blink-only into a standalone garbage collection library inside V8, aimed at other V8 embedders and C++ developers generally.
Why it matters
Blink's rendering engine is a large C++ codebase whose DOM objects are deeply entangled with the JavaScript objects V8 manages, which makes garbage collection there unusually hard: a collector has to reclaim C++ memory without stalling the main thread that also runs the page's JavaScript and rendering. Oilpan's shift from stop-the-world to incremental to concurrent sweeping is a direct answer to that, and the reported 25 to 50 percent (42% average) cut in main-thread sweeping time translates into less jank for whatever is running in the browser at that moment. The stated move of Oilpan out of Blink and into V8 as a general-purpose library also matters beyond Chrome: it turns a Chromium-specific mechanism into infrastructure any V8 embedder could reuse for managing C++ memory.
Who it affects
Directly, this is for Chromium and Blink engineers, and for C++ developers who write Oilpan-managed types inside Blink and have to follow its rules for destructors and finalizers. Once Oilpan ships as a standalone V8 library, the post's stated goal is to extend that reach to other V8 embedders and to C++ developers more broadly, not just Chromium. Indirectly, Chrome users benefit from the measured reduction in main-thread sweeping time, since it frees up the same thread that renders pages and runs page JavaScript.
How to use it
A type opts into Oilpan management by inheriting from GarbageCollected
How solid is it
This is an official V8 engineering blog post, the first in a planned series, written from inside the team that builds and maintains Oilpan and V8. The headline performance number, a 25 to 50 percent reduction in main-thread sweeping time with a 42% average, comes from V8's own real-world benchmarking framework rather than a synthetic microbenchmark, and background sweeping is not experimental: the post states it has already shipped in Chrome M78, so the design has been running in a production browser rather than only in a lab.
Risks and caveats
The post does not name an individual author or engineer, and it gives no calendar date for either the post itself or for when background sweeping shipped, only the Chrome version, M78. It also gives no timeline for when Oilpan's move from Blink into a standalone V8 library will be complete; the post frames it as ongoing, ahead of 'a release that can be used by all users of V8,' without committing to a date. On the technical side, the finalizer constraints are real limits, not footnotes: finalizers cannot touch other heap objects, run in no defined order, and remaining finalizer overhead is explicitly called out as the next thing the team is working to reduce, meaning the reported gains apply to sweeping specifically and not to the whole collection pause.