

























@@ -14,6 +14,18 @@ export function parsePsCpuTimeMs(raw: string): number | null {
1414return null;
1515}
161617+export function parsePsRssBytes(raw: string): number | null {
18+const trimmed = raw.trim();
19+if (!trimmed) {
20+return null;
21+}
22+const rssKiB = Number(trimmed);
23+if (!Number.isFinite(rssKiB) || rssKiB < 0) {
24+return null;
25+}
26+return Math.round(rssKiB * 1024);
27+}
28+1729export function readProcessTreeCpuMs(rootPid: number | null | undefined): number | null {
1830if (
1931typeof rootPid !== "number" ||
@@ -70,3 +82,60 @@ export function readProcessTreeCpuMs(rootPid: number | null | undefined): number
7082}
7183return totalCpuMs;
7284}
85+86+export function readProcessTreeRssBytes(rootPid: number | null | undefined): number | null {
87+if (
88+typeof rootPid !== "number" ||
89+!Number.isInteger(rootPid) ||
90+rootPid <= 0 ||
91+process.platform === "win32"
92+) {
93+return null;
94+}
95+const result = spawnSync("ps", ["-eo", "pid=,ppid=,rss="], {
96+encoding: "utf8",
97+stdio: ["ignore", "pipe", "ignore"],
98+});
99+if (result.status !== 0) {
100+return null;
101+}
102+103+const childrenByParent = new Map<number, number[]>();
104+const rssByPid = new Map<number, number>();
105+for (const line of result.stdout.split("\n")) {
106+const match = line.trim().match(/^(\d+)\s+(\d+)\s+(\S+)$/u);
107+if (!match) {
108+continue;
109+}
110+const [, pidRaw, ppidRaw, rssRaw] = match;
111+const pid = Number(pidRaw);
112+const ppid = Number(ppidRaw);
113+const rssBytes = parsePsRssBytes(rssRaw ?? "");
114+if (!Number.isInteger(pid) || !Number.isInteger(ppid) || rssBytes === null) {
115+continue;
116+}
117+rssByPid.set(pid, rssBytes);
118+const children = childrenByParent.get(ppid) ?? [];
119+children.push(pid);
120+childrenByParent.set(ppid, children);
121+}
122+if (!rssByPid.has(rootPid)) {
123+return null;
124+}
125+126+let totalRssBytes = 0;
127+const seen = new Set<number>();
128+const stack: number[] = [rootPid];
129+while (stack.length > 0) {
130+const pid = stack.pop();
131+if (pid === undefined || seen.has(pid)) {
132+continue;
133+}
134+seen.add(pid);
135+totalRssBytes += rssByPid.get(pid) ?? 0;
136+for (const childPid of childrenByParent.get(pid) ?? []) {
137+stack.push(childPid);
138+}
139+}
140+return totalRssBytes;
141+}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。