Files
scriptc/tests/corpus/process-constrained-memory.ts
T
Malte Ubl 09118a3c25 Read the process's own cgroup in process.constrainedMemory() like libuv
scr_constrained_memory read /sys/fs/cgroup/memory.max, the root of the cgroup mount, and answered
0 for "max". Node's process.constrainedMemory() is libuv's uv_get_constrained_memory (libuv 1.51
in Node 24.15): the cgroup named by /proc/self/cgroup, the smaller of memory.max and memory.high
(v2) or of memory.limit_in_bytes and memory.soft_limit_in_bytes (v1, falling back to the
controller's root), with "max" and v1's page-aligned LONG_MAX read as UINT64_MAX and an unreadable
file making the answer 0. The two only agreed inside a cgroup namespace; in a nested cgroup or a
systemd scope the native build reported the root's limit (17179869184 in a 16 GB sandbox where Node
answers 18446744073709552000, or 2147483648 under memory.high=2G), so programs that size
themselves by it ran out of memory.

process.availableMemory() follows uv_get_available_memory too: under a constraint no larger than the
machine's memory, the constraint minus the cgroup's current usage; otherwise MemAvailable, then
sysinfo's freeram.

The corpus program prints the exact constraint, so Node and the native build must read the same
cgroup.
2026-10-12 07:22:54 -07:00

16 lines
946 B
TypeScript

// process.constrainedMemory() is libuv's uv_get_constrained_memory: on Linux
// the smaller of memory.max and memory.high of the process's own cgroup
// (named by /proc/self/cgroup), UINT64_MAX when both are "max", and 0 where
// there is no cgroup; 0 elsewhere. It is printed exactly, so Node and the
// native binary must read the same cgroup. availableMemory() changes with
// usage, so only its bound is checked: under a constraint no larger than the
// machine it is the constraint minus the cgroup's usage.
import { totalmem } from "node:os";
const constrained = process.constrainedMemory();
console.log("constrained:", constrained);
console.log("constrained is a number:", typeof constrained === "number" && constrained >= 0);
const available = process.availableMemory();
const bound = constrained > 0 && constrained <= totalmem() ? constrained : totalmem();
console.log("available within bound:", available >= 0 && available <= bound);