9 Garbage Collection
This chapter covers
- Seeing what follows from the spec's silence on garbage collection
- Tracing V8's generational Orinoco collector
- Comparing V8’s garbage collection to JSC's non-moving Riptide collector
- Spotting allocation patterns that cause GC thrashing
- Releasing references safely with WeakRef, WeakMap, and FinalizationRegistry
So far, we’ve hand waved around memory management. We’re going to fix that now.
We've seen how microtasks, macrotasks, and rendering callbacks compete for the main thread. The garbage collector is competing for it too, and it's the one most developers forget about.
JavaScript developers often treat memory like a hotel room: You check in, use whatever you want, and someone else cleans up after you leave. You've probably heard that analogy before. What it leaves out is that the cleaning crew doesn't wait until you check out.
For instance, a Node.js server handling server-side rendering for a React application is running under steady traffic. The code works perfectly and is as tuned for performance as a React application can be. However, every few seconds, response times spike by hundreds of milliseconds for no apparent reason. Database latency is fine, the network is clean, and your logging shows that nothing is going wrong. The spikes come and go seemingly without explanation.