fix provider process memory accounting

This commit is contained in:
Codex
2026-05-17 16:43:11 +00:00
parent bdaae79834
commit 3ed8c102c1
10 changed files with 82 additions and 16 deletions
+18 -5
View File
@@ -845,7 +845,7 @@ function NodeMonitorPage({ nodes, systemStatuses, tasks, onRaw, refresh }: AnyRe
h("article", null, h("b", null, "CPU"), h("span", null, "从 /proc/stat 计算相邻采样差值,首个采样用 load/cores 近似")),
h("article", null, h("b", null, "Memory"), h("span", null, "实际内存 = MemTotal - MemFree - Buffers - Cached - SReclaimable + Shmem,不把 page cache / buffer 计入占用")),
h("article", null, h("b", null, "Disk"), h("span", null, "使用 df -PB1 对配置路径采样,默认监控根文件系统")),
h("article", null, h("b", null, "Process"), h("span", null, "从 /proc/[pid] 采集进程 CPU、实际内存 RSS、线程数和磁盘 I/O 速率;表格默认按内存占用降序")),
h("article", null, h("b", null, "Process"), h("span", null, "从 /proc/[pid] 采集进程 CPU、实际内存 PSS、RSS、线程数和磁盘 I/O 速率;PSS 不重复计算共享内存,表格默认按内存占用降序")),
),
),
),
@@ -855,8 +855,12 @@ function NodeMonitorPage({ nodes, systemStatuses, tasks, onRaw, refresh }: AnyRe
type ProcessSortKey = "memory" | "cpu" | "disk" | "pid" | "name" | "user" | "threads" | "runtime";
function processMemoryBytes(row: AnyRecord): number {
return asNumber(row.memoryBytes, asNumber(row.pssBytes, asNumber(row.rssBytes)));
}
function processSortValue(row: AnyRecord, key: ProcessSortKey): string | number {
if (key === "memory") return asNumber(row.rssBytes);
if (key === "memory") return processMemoryBytes(row);
if (key === "cpu") return asNumber(row.cpuPercent);
if (key === "disk") return asNumber(row.readBytesPerSecond) + asNumber(row.writeBytesPerSecond);
if (key === "pid") return asNumber(row.pid);
@@ -879,6 +883,8 @@ function ProcessResourceTable({ current, onRaw }: AnyRecord) {
const contextLoading = React.useContext(LoadingContext);
const processSummary = current?.processSummary && typeof current.processSummary === "object" ? current.processSummary : {};
const processes = Array.isArray(current?.processes) ? current.processes : [];
const memoryMode = String(processSummary.memoryMode || "");
const memoryModeLabel = memoryMode === "pss_smaps_rollup" ? "PSS" : "RSS fallback";
const rows = useMemo(() => {
const direction = sort.direction === "asc" ? 1 : -1;
return [...processes].sort((left: AnyRecord, right: AnyRecord) => {
@@ -913,6 +919,7 @@ function ProcessResourceTable({ current, onRaw }: AnyRecord) {
),
h("div", { className: "process-resource-actions" },
h("span", { className: "data-chip" }, "默认按内存排序"),
h("span", { className: "data-chip" }, `内存口径 ${memoryModeLabel}`),
h("span", { className: "data-chip" }, `${asNumber(processSummary.visible, rows.length)} / ${asNumber(processSummary.total, rows.length)} 进程`),
h(RawButton, { title: "Process Resource Snapshot", data: { processSummary, processes }, onOpen: onRaw, testId: "raw-process-resources" }),
),
@@ -927,17 +934,18 @@ function ProcessResourceTable({ current, onRaw }: AnyRecord) {
h("th", null, "状态"),
sortHeader("CPU", "cpu"),
sortHeader("内存", "memory"),
h("th", null, "RSS"),
h("th", null, "PSS / RSS"),
sortHeader("磁盘 I/O", "disk"),
sortHeader("线程", "threads"),
sortHeader("运行时长", "runtime"),
)),
h("tbody", null, rows.map((row: AnyRecord) => {
const diskRate = asNumber(row.readBytesPerSecond) + asNumber(row.writeBytesPerSecond);
const memoryBytes = processMemoryBytes(row);
return h("tr", {
key: `${row.pid}-${row.startedAt}`,
"data-testid": `process-row-${safeId(row.pid)}`,
"data-memory-bytes": String(asNumber(row.rssBytes)),
"data-memory-bytes": String(memoryBytes),
"data-cpu-percent": String(asNumber(row.cpuPercent)),
"data-disk-bps": String(diskRate),
"data-pid": String(asNumber(row.pid)),
@@ -953,7 +961,12 @@ function ProcessResourceTable({ current, onRaw }: AnyRecord) {
h("td", null, h("span", { className: `process-state state-${safeId(row.state || "unknown")}` }, row.state || "?")),
h("td", null, h(ProcessMeter, { value: row.cpuPercent, label: fmtLoosePercent(row.cpuPercent), tone: "cpu" })),
h("td", null, h(ProcessMeter, { value: row.memoryPercent, label: fmtPercent(row.memoryPercent), tone: "memory" })),
h("td", null, fmtBytes(row.rssBytes)),
h("td", null,
h("div", { className: "process-io-cell" },
h("strong", null, fmtBytes(memoryBytes)),
h("span", null, `RSS ${fmtBytes(row.rssBytes)}`),
),
),
h("td", null, h("div", { className: "process-io-cell" },
h("strong", null, fmtBytesRate(diskRate)),
h("span", null, `R ${fmtBytesRate(row.readBytesPerSecond)} / W ${fmtBytesRate(row.writeBytesPerSecond)}`),