()
| 85 | * once per call (pool sizing runs it once per init; a few ms). Never throws. |
| 86 | */ |
| 87 | export function darwinMemoryAvailable(): number | null { |
| 88 | if (process.platform !== 'darwin') return null; |
| 89 | try { |
| 90 | const out = execFileSync('/usr/bin/vm_stat', { encoding: 'utf8', timeout: 2000 }); |
| 91 | const pageMatch = /page size of (\d+) bytes/.exec(out); |
| 92 | const pageSize = pageMatch ? Number.parseInt(pageMatch[1]!, 10) : 16384; |
| 93 | const count = (label: string): number => { |
| 94 | const m = new RegExp(`^${label}:\\s+(\\d+)`, 'm').exec(out); |
| 95 | return m ? Number.parseInt(m[1]!, 10) : 0; |
| 96 | }; |
| 97 | const pages = |
| 98 | count('Pages free') + |
| 99 | count('Pages inactive') + |
| 100 | count('Pages speculative') + |
| 101 | count('Pages purgeable'); |
| 102 | const bytes = pages * pageSize; |
| 103 | return bytes > 0 && Number.isFinite(bytes) ? bytes : null; |
| 104 | } catch { |
| 105 | return null; |
| 106 | } |
| 107 | } |
| 108 | |
| 109 | /** |
| 110 | * The budget pool sizing divides: the smaller of system free memory and the |
no test coverage detected