Why Assigning Beyond Array Length Saves Memory in V8

An in‑depth analysis shows why assigning a value at index 99999 in a large JavaScript array triggers V8 to switch from fast to slow (dictionary) mode, dramatically reducing memory usage by expanding capacity and converting holey arrays into a more efficient storage structure.

Taobao Frontend Technology
Taobao Frontend Technology
Taobao Frontend Technology
Why Assigning Beyond Array Length Saves Memory in V8

While debugging a memory issue, two similar code snippets revealed a surprising difference in heap usage when run under Node.js with V8.

const a = new Array(99999);
a[99998] = undefined;
const b = new Array(99999);
b[99999] = undefined;

Heap snapshots taken at the start and end of each run show that the second snippet consumes noticeably less memory. The key lies in the out‑of‑bounds assignment to index 99999.

V8 stores arrays in two modes: fast (contiguous memory) and slow (hash‑table based). Arrays are also classified as Packed when all indices are initialized, or Holey when there are gaps. For example, ['a', 'b', 'c'] is packed, while ['a', , , 'd'] is holey, wasting memory for the empty slots.

V8 optimizes large holey arrays by converting them to the slow mode, using a dictionary to avoid the waste of a large FixedArray. This behavior is described in the V8 blog.

Debugging with v8‑debug (installable via jsvu) shows the first array as a FixedArray and the second as a Dictionary. The conversion decision occurs in the V8 call chain:

Object::SetProperty
  → Object::AddDataProperty
    → JSObject::AddDataElement
      → ShouldConvertToSlowElements

The ShouldConvertToSlowElements method checks whether an array should switch to the slow (dictionary) mode (see v8/src/objects/js-objects-inl.h#L794).

When the index 99998 is set, it is within the current capacity (99999), so the method returns false and no conversion occurs.

Setting the index 99999 exceeds the original capacity, triggering an expansion algorithm (capacity + capacity/2 + 16), growing the array to about 150 000 slots. V8 then calls GetFastElementsUsage to count non‑hole elements, multiplies the count by kPreferFastElementsSizeFactor (value 3) and kEntrySize (value 2), and compares the product to the new capacity. Because the product (0) is less than the new capacity, the array is converted to the slow (dictionary) mode, which stores data more compactly and saves a large amount of memory.

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 OptimizationNode.jsArrayV8
Taobao Frontend Technology
Written by

Taobao Frontend Technology

The frontend landscape is constantly evolving, with rapid innovations across familiar languages. Like us, your understanding of the frontend is continually refreshed. Join us on Taobao, a vibrant, all‑encompassing platform, to uncover limitless potential.

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.