Understanding JavaScript Memory Management and Common Memory Leaks

This article explains JavaScript's memory lifecycle, defines memory leaks, enumerates typical leak patterns such as accidental globals, timers, closures and DOM references, and describes the underlying garbage‑collection strategies (mark‑and‑sweep and reference counting) together with practical mitigation techniques.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Understanding JavaScript Memory Management and Common Memory Leaks

Preface

Regardless of the programming language, the basic memory lifecycle is the same: allocate the memory you need, use the allocated memory (read/write), and release it when it is no longer required.

All languages clearly define the second part; the first and third parts are explicit in low‑level languages but are often implicit in high‑level languages like JavaScript.
Note: JavaScript is a high‑level interpreted scripting language that runs in the browser.

In Chrome, V8 limits memory usage to about 1.4 GB on 64‑bit systems and 0.7 GB on 32‑bit systems. The limitation stems from V8’s original design for browsers, where massive memory consumption is rare, and from the cost of garbage‑collection pauses when cleaning large heaps.

JavaScript automatically allocates memory when variables (objects, strings, etc.) are created and “automatically” releases it when they are no longer used; this release process is called garbage collection.

This “automatic” behavior often misleads developers into ignoring memory management, which can cause memory leaks.

1. What Is a Memory Leak?

A program needs memory; the operating system or runtime provides it on demand. For long‑running services, memory that is no longer needed must be released promptly, otherwise performance degrades or the process may crash.

When memory that is no longer needed is not released, it is called a memory leak.

2. Common Memory Leaks

Poorly written JavaScript can produce subtle and harmful memory leaks, especially on memory‑constrained devices or when functions are invoked frequently. Most leaks arise from unreasonable references.

2.1 Accidental Global Variables

Accidentally creating globals is the most common and easiest‑to‑fix leak. The following code omits any declaration keyword:

function setName() {
  name = 'yuanyuan';
}

The interpreter treats name as a property of the global window object (i.e., window.name = 'yuanyuan'). As long as window persists, the property remains. Adding var, let or const before the variable name confines it to the function scope and eliminates the leak.

2.2 Forgotten Timers

Timers can silently cause leaks when their callbacks close over external variables:

let name = 'yuanyuan';
setInterval(() => {
  console.log(name);
}, 100);

As long as the interval runs, the closed‑over name stays in memory.

2.3 Improper Closures

Closures can unintentionally retain references:

let outer = function() {
  let name = 'yuanyuan';
  return function() {
    return name;
  };
};

Because the inner function keeps a reference to name, the memory for name cannot be reclaimed while outer exists.

2.4 Unreleased DOM References

When a DOM element is removed from the document but still referenced from JavaScript, it cannot be collected:

// Object holding a DOM reference
var elements = {
  btn: document.getElementById('btn'),
};
function doSomeThing() {
  elements.btn.click();
}
function removeBtn() {
  document.body.removeChild(document.getElementById('button'));
  // elements still holds a reference to btn, preventing GC
}

Clearing the reference (e.g., elements.btn = null;) allows the element to be reclaimed.

3. Garbage‑Collection Mechanisms

Languages like C require manual memory release, while most modern languages provide automatic garbage collection.

char *buffer;
buffer = (char*)malloc(42);
// Do something with buffer
free(buffer);

JavaScript uses a garbage collector that periodically identifies unreachable values and frees their memory. Two primary strategies are used:

3.1 Mark‑and‑Sweep

When a variable enters a context (e.g., a function), it is marked as “in‑use”. When it leaves the context, the mark is removed. During a GC cycle, all unmarked values are reclaimed.

3.2 Reference Counting

Each value tracks how many references point to it; when the count drops to zero, the value can be freed. This method suffers from circular references, where two objects reference each other, preventing their counts from ever reaching zero.

Example of a circular reference:

function problem() {
  let objectA = new Object();
  let objectB = new Object();
  objectA.someOtherObject = objectB;
  objectB.anotherObject = objectA;
}

Older IE versions also used COM objects that rely on reference counting, leading to leaks when JavaScript objects and DOM elements form cycles. Breaking the cycle (e.g., setting the references to null) resolves the issue.

4. Memory‑Management Practices

JavaScript values are either primitive (stored on the stack) or reference types (objects stored on the heap). Primitive values are copied on assignment; reference values copy only the pointer.

All variables exist within an execution context (global, function, or block). The context determines the variable’s lifetime and when it becomes eligible for garbage collection.

Key points for developers:

Leaving a scope automatically marks values as collectible.

Using const and let (block‑scoped) can allow the GC to reclaim memory earlier than var (function‑scoped).

Explicitly nullify global variables or long‑lived object properties when they are no longer needed.

function createPerson(name) {
  let localPerson = new Object();
  localPerson.name = name;
  return localPerson;
}
let globalPerson = createPerson('Nicholas'); // later no longer needed
globalPerson = null;

Setting a variable to null breaks the reference; the next GC run can then reclaim the memory.

References

JavaScript: The Good Parts (4th Edition)

Memory Management

JavaScript Memory Leak Tutorial

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaScriptMemory Managementfrontend developmentGarbage Collectionmemory leak
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.