Skip to content

Turbopack: don't grow effect vectors inside the analyzer arena - #101480

Merged
jimmyhmiller merged 2 commits into
canaryfrom
jimmym/analyzer-effect-vecs
Nov 11, 2026
Merged

jimmyhmiller merged 2 commits into
canaryfrom
jimmym/analyzer-effect-vecs

Conversation

@jimmyhmiller

Copy link
Copy Markdown
Contributor

The analyzer collects effects into bump-allocated vectors while it walks a module. A bump arena can't free memory, so every time one of those vectors grows, its old buffer stays allocated until the analysis finishes. Effect vectors grow constantly, so a large part of the arena ends up being abandoned buffers.

Collect effects in heap vectors instead, and copy each finished block into the arena at its exact size. The arena then only holds what is actually kept, as intended when effects moved into the arena in #94614.

No change in output. Measured on analyze_ecmascript_module alone, release build, 5 alternating rounds against the parent commit, as median paired changes:

Input Peak memory Bytes allocated Allocations CPU
8,000 modules -20.1% -8.4% +3.3% -0.9%
Generated stress -22.3% -14.9% +0.0% -1.0%
Four large benchmarks +0.0% +6.7% +3.1% -4.1%

Peak memory is the sum of each module's peak live allocations. On the 8,000 modules it goes from 7,652 MB to 6,118 MB. The CPU changes are within noise. The four large benchmark files gain bytes from the heap vectors' own growth and the final copy, without a change in peak.

@jimmyhmiller
jimmyhmiller requested a review from a team November 9, 2026 20:24
@github-actions

github-actions Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Tests Passed

Commit: f94710e
View workflow run

@github-actions github-actions Bot added the Turbopack Related to Turbopack with Next.js. label Nov 9, 2026
The analyzer collects effects into bump-allocated vectors while it walks
a module. A bump arena can't free memory, so every time one of those
vectors grows, its old buffer stays allocated until the analysis
finishes. Effect vectors grow constantly, so a large part of the arena
ends up being abandoned buffers.

Collect effects in heap vectors instead, and copy each finished block
into the arena at its exact size. The arena then only holds what is
actually kept, as intended when effects moved into the arena in #94614.

No change in output. Measured on analyze_ecmascript_module alone,
release build, 5 alternating rounds against the parent commit, as
median paired changes:

| Input                 | Peak memory | Bytes allocated | Allocations | CPU   |
| --------------------- | ----------- | --------------- | ----------- | ----- |
| 8,000 modules         | -20.1%      | -8.4%           | +3.3%       | -0.9% |
| Generated stress      | -22.3%      | -14.9%          | +0.0%       | -1.0% |
| Four large benchmarks | +0.0%       | +6.7%           | +3.1%       | -4.1% |

Peak memory is the sum of each module's peak live allocations. On the
8,000 modules it goes from 7,652 MB to 6,118 MB. The CPU changes are
within noise. The four large benchmark files gain bytes from the heap
vectors' own growth and the final copy, without a change in peak.
@jimmyhmiller
jimmyhmiller force-pushed the jimmym/analyzer-effect-vecs branch from f0d61da to f94710e Compare November 10, 2026 15:24
@jimmyhmiller
jimmyhmiller merged commit 2be8353 into canary Nov 11, 2026
108 checks passed
@jimmyhmiller
jimmyhmiller deleted the jimmym/analyzer-effect-vecs branch November 11, 2026 17:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Turbopack Related to Turbopack with Next.js.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants