Mastering JavaScript Memory Management: GC Algorithms and Performance Tips
Understanding how JavaScript manages memory, this article explains garbage collection concepts such as Stop‑The‑World pauses, reference counting, mark‑sweep, mark‑compact, incremental marking, and V8’s generational strategies, while offering practical code examples and optimization techniques to prevent leaks and improve performance.
JavaScript Memory Management
Applications occupy memory while running and must release unused memory; failure to do so leads to continuously rising memory usage, slower execution, and possible crashes.
Memory : a readable‑writable address space.
Management : manual request, use, and release of that space.
Memory Management : developers explicitly allocate, use, and free memory.
Process : allocate → use → release.
Languages like C require manual release, while most modern languages (e.g., Java, JavaScript) provide automatic garbage collection (GC).
Stop‑The‑World (STW)
Before a GC algorithm runs, the JavaScript engine pauses application execution, performs garbage collection, then resumes. A 50 ms GC pause means the app is frozen for 50 ms.
When an Object Becomes Garbage
It is no longer referenced.
It cannot be reached from the root set.
Common GC Algorithms
Reference Counting
Mark‑Sweep
Mark‑Compact
Generational Collection
Reference Counting
Early browsers kept a table of reference counts; when a value’s count drops to zero, it is reclaimed. Example:
const user1 = {age: 11};
const user2 = {age: 22};
const user3 = {age: 33};
const userList = [user1.age, user2.age, user3.age];After the loop, user1, user2, and user3 are still referenced by userList, so they are not collected.
When a function finishes, its local variables’ counts become zero and are reclaimed:
function fn() {
const num1 = 1;
const num2 = 2;
}
fn();Reference counting fails with cyclic references:
function objGroup(obj1, obj2) {
obj1.next = obj2;
obj2.prev = obj1;
return {o1: obj1, o2: obj2};
}
let obj = objGroup({name: 'obj1'}, {name: 'obj2'});
console.log(obj);Both objects reference each other, so their counts never reach zero, causing a leak. Maintaining a separate table also adds memory overhead.
Advantages
Immediate reclamation when count reaches zero.
Minimal pause time.
Disadvantages
Cannot collect cyclic references.
Higher space cost for the reference table.
Mark‑Sweep
Two phases: mark reachable (live) objects, then sweep away unmarked (dead) objects.
Traverse all objects to mark live ones.
Traverse again to free unmarked objects.
Release the reclaimed space.
V8 uses this algorithm for the old generation because it can collect cycles.
Mark‑Compact
Improves on mark‑sweep by eliminating fragmentation. After marking, live objects are moved (compacted) to one side, and the free space becomes contiguous.
Fragmentation example (red = root, blue = reclaimed):
Compaction reduces fragmentation but adds the cost of moving objects, making reclamation slower.
Incremental Marking
To reduce STW pauses, V8 splits the marking phase into many small steps, interleaving application execution between steps.
Since 2011, V8’s incremental marking cuts maximum pause time to about one‑sixth of the original.
V8 Garbage‑Collection Strategy
V8 adopts generational collection: the heap is split into a young generation (new objects) and an old generation (long‑lived objects). Different algorithms are applied based on object age.
Young generation: uses copying (Scavenge) algorithm, implemented with Cheney’s algorithm.
Old generation: primarily uses mark‑sweep; falls back to mark‑compact when memory is tight.
Scavenge copies live objects from the “From” space to the “To” space; after copying, the spaces swap roles.
Objects promoted from young to old when the “To” space exceeds 25 % usage after a copy.
Memory‑Leak Detection
Use the browser’s Performance panel to monitor memory while running code that deliberately consumes memory:
<button class="btn">点击</button>
<script>
const btn = document.querySelector('.btn');
const arrList = [];
btn.onclick = function() {
for(let i = 0; i < 100000; i++) {
const p = document.createElement('p');
document.body.appendChild(p);
}
arrList.push(new Array(1000000).join('x'));
};
</script>During execution, sharp drops in the memory graph indicate GC pauses.
Performance Optimizations
Avoid global variables – they stay on window and keep a reference count.
Reduce conditional nesting
function doSomething(part, chapter) {
const parts = ['ES2016','工程化','Vue','React','Node'];
if (!part) { console.log('请确认模块信息'); return; }
if (!parts.includes(part)) return;
console.log('属于当前课程');
if (chapter > 5) console.log('您需要提供 VIP 身份');
}Cache frequently used data
var oBox = document.getElementById('skip');
function hasEle(ele, cls) { return ele.className === cls; }
console.log(hasEle(oBox, 'skip'));Minimize work inside loops
var arr = ['Hello World!','25','岂曰无衣,与子同袍'];
var len = arr.length;
for (var i = 0; i < len; i++) console.log(arr[i]);Use event delegation
var ul = document.querySelector('.ul');
ul.addEventListener('click', function(ev) {
if (ev.target.nodeName.toLowerCase() === 'li')
console.log(ev.target.innerHTML);
});Avoid closure traps
function foo() {
let el = document.querySelector('.btn');
el.onclick = function() { console.log(el.className); };
el = null; // break the closure reference
}
foo();Applying these techniques reduces memory pressure and improves overall responsiveness.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Huawei Cloud Developer Alliance
The Huawei Cloud Developer Alliance creates a tech sharing platform for developers and partners, gathering Huawei Cloud product knowledge, event updates, expert talks, and more. Together we continuously innovate to build the cloud foundation of an intelligent world.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
