Skip to content

perf: trim glibc malloc arena after module loading#32662

Merged
bartlomieju merged 4 commits intomainfrom
fix/linux-malloc-trim-after-module-load
Mar 17, 2026
Merged

perf: trim glibc malloc arena after module loading#32662
bartlomieju merged 4 commits intomainfrom
fix/linux-malloc-trim-after-module-load

Conversation

@bartlomieju
Copy link
Copy Markdown
Member

Summary

  • Calls malloc_trim(0) on Linux after the main/side module loading phase completes, forcing glibc to release unused heap pages back to the OS
  • Addresses 3-5x higher RSS on Linux vs Windows when loading large TypeScript codebases (e.g. generated OpenAPI clients)
  • Module compilation creates heavy allocation churn that glibc's allocator retains in its arena; malloc_trim reclaims this

Root cause

glibc's malloc doesn't automatically return freed memory to the OS — it keeps freed pages in its arena for future reuse. On Windows, the NT heap manager coalesces and releases freed memory much more aggressively. After TypeScript compilation/module loading (which creates many temporary allocations for AST nodes, source maps, etc.), glibc holds onto all that memory even though it's been freed.

Why this is safe

  • malloc_trim is a standard glibc function, safe to call at any time
  • It only releases memory already freed — no impact on live allocations
  • Guarded by #[cfg(target_os = "linux")] — no-op on other platforms
  • The existing DENO_USR2_MEMORY_TRIM mechanism already uses the same call, just triggered externally via SIGUSR2

Closes #25722

Test plan

  • Verify compilation succeeds on Linux (cargo check -p deno)
  • Run spec tests (cargo test specs)
  • Test with a large TypeScript project on Linux and measure RSS before/after with Deno.memoryUsage().rss
  • Verify no regression on Windows/macOS (the malloc_trim call is cfg-gated to Linux only)

🤖 Generated with Claude Code

bartlomieju and others added 2 commits March 12, 2026 15:06
On Linux, glibc's malloc doesn't release freed memory back to the OS,
causing RSS to be 3-5x higher than on Windows for the same workload.
This is especially noticeable when loading large TypeScript codebases
(e.g. generated OpenAPI clients) where module compilation creates heavy
allocation churn.

Call `malloc_trim(0)` after the main/side module loading phase completes
to force glibc to release unused heap pages back to the OS.

Closes #25722

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The `libc` crate was used in `worker.rs` but not declared as a
dependency of `deno_lib`, causing build failures on Linux.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@bartlomieju bartlomieju requested a review from nathanwhit March 15, 2026 12:14
bartlomieju and others added 2 commits March 17, 2026 15:46
Co-authored-by: Divy <dj.srivastava23@gmail.com>
Signed-off-by: Bartek Iwańczuk <biwanczuk@gmail.com>
- Fix indentation of #[cfg] attribute (3 spaces → 4)
- Use consistent cfg guard in execute_side_module: target_env = "gnu"
  is needed since malloc_trim is glibc-specific

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@bartlomieju bartlomieju enabled auto-merge (squash) March 17, 2026 15:38
@bartlomieju bartlomieju changed the title perf(linux): trim glibc malloc arena after module loading perf: trim glibc malloc arena after module loading Mar 17, 2026
@bartlomieju bartlomieju merged commit 922a9ca into main Mar 17, 2026
113 checks passed
@bartlomieju bartlomieju deleted the fix/linux-malloc-trim-after-module-load branch March 17, 2026 16:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Deno RAM usage on Linux 5x higher than on Windows

2 participants