()
| 172 | * correct value via `MemAvailable` in /proc/meminfo. |
| 173 | */ |
| 174 | export function getAvailableMemoryMb(): number { |
| 175 | const fallback = bytesToMb(freemem()); |
| 176 | |
| 177 | if (platform() === "darwin") { |
| 178 | try { |
| 179 | const raw = execSync("vm_stat", { encoding: "utf-8", timeout: 5000 }); |
| 180 | const pageSize = parseInt(raw.match(/page size of (\d+)/)?.[1] ?? "0", 10); |
| 181 | if (!pageSize) return fallback; |
| 182 | |
| 183 | const pages = (key: string) => |
| 184 | parseInt(raw.match(new RegExp(`${key}:\\s+(\\d+)`))?.[1] ?? "0", 10); |
| 185 | |
| 186 | const available = |
| 187 | (pages("Pages free") + |
| 188 | pages("Pages inactive") + |
| 189 | pages("Pages purgeable") + |
| 190 | pages("Pages speculative")) * |
| 191 | pageSize; |
| 192 | |
| 193 | return available > 0 ? bytesToMb(available) : fallback; |
| 194 | } catch { |
| 195 | return fallback; |
| 196 | } |
| 197 | } |
| 198 | |
| 199 | if (platform() === "linux") { |
| 200 | try { |
| 201 | const meminfo = readFileSync("/proc/meminfo", "utf-8"); |
| 202 | const match = meminfo.match(/MemAvailable:\s+(\d+)\s+kB/); |
| 203 | if (match) { |
| 204 | return Math.trunc(parseInt(match[1]!, 10) / 1024); |
| 205 | } |
| 206 | return fallback; |
| 207 | } catch { |
| 208 | return fallback; |
| 209 | } |
| 210 | } |
| 211 | |
| 212 | return fallback; |
| 213 | } |
no test coverage detected