Electron ProcessMetric 深度解析:读懂 app.getAppMetrics() 返回的进程指标结构 Electron ProcessMetric 深度解析读懂 app.getAppMetrics() 返回的进程指标结构【免费下载链接】electron:electron: Build cross-platform desktop apps with JavaScript, HTML, and CSS项目地址: https://gitcode.com/GitHub_Trending/el/electronElectron 的多进程架构中主进程可以通过app.getAppMetrics()查看应用内所有子进程的 CPU 与内存占用而该方法返回的正是ProcessMetric对象数组——它是 Electron 官方 API 中进程级资源监控的数据基础。本文从ProcessMetric各字段定义出发结合测量语义区间平均机制、源码中的 C 组装逻辑与测试套件的断言帮你掌握一个在 Linux / macOS / Windows 上都能正确实现、可复制落地的进程监控方案。ProcessMetric 对象从何而来ProcessMetric不是独立 API而是主进程方法app.getAppMetrics()的返回结构。app模块文档中对该方法的说明是app.getAppMetrics()返回ProcessMetric[]数组对应与应用相关的所有进程的内存与 CPU 使用统计cpu.percentCPUUsage与cpu.idleWakeupsPerSecond是自上次调用以来的平均值每次调用会同时为每个进程开启新的测量区间主进程中的其他代码包括依赖库共享这些区间。一个典型的 Electron 应用包含Browser主进程、GPU进程、若干Tab渲染进程与多个Utility进程Network Service、Audio Service 等上图即是 Chromium 多进程模型的示意而getAppMetrics()的返回值正是对这张图中每个节点的量化快照。字段逐一详解ProcessMetric的完整定义见 docs/api/structures/process-metric.md全部字段整理如下字段类型平台说明pidInteger全部进程 IDtypestring全部进程类型取值见下文serviceNamestring可选全部进程的非本地化名称namestring可选全部进程名如 Utility 进程的服务名cpuCPUUsage全部进程 CPU 使用率creationTimenumber全部进程创建时间距 epoch 的毫秒数memoryMemoryInfo见正文进程内存信息sandboxedboolean可选macOS / Windows进程是否被操作系统级沙箱化integrityLevelstring可选Windows进程完整性级别进程标识pid、type与creationTime为什么pid不足以唯一标识进程。文档明确指出由于进程死亡后pid可能被复用应使用pid与creationTime的组合来唯一标识一个进程。creationTime以 epoch 毫秒时间戳表示在实现追踪某个进程的内存增长这类监控逻辑时尤为关键——仅用pid做键一旦旧进程退出、新进程复用了相同编号统计就会混入新进程的数据。type的取值包括Browser浏览器主进程Tab标签页/渲染进程Utility工具进程Zygotezygote 进程LinuxSandbox helper沙箱辅助进程GPUGPU 进程Pepper PluginPepper 插件进程Pepper Plugin BrokerPepper 插件代理Unknown未知类型从源码结构看这个英文类型名由App::GetAppMetrics中调用 Chromium 的content::GetProcessTypeNameInEnglish()直接生成因此type是固定的英文字符串与系统语言环境无关可以放心地在跨平台代码中作为分支依据。服务标识serviceName与nameserviceName是非本地化的进程名。测试套件对其有明确断言Utility与GPU类型的进程必须有非空的serviceName见 spec/api-app-spec.ts。源码中仅在非空时写入该字段因此消费方应按可选字段处理name是进程名文档给出了 Utility 进程的示例Audio Service、Content Decryption Module Service、Network Service、Video Capture等同样仅在非空时写入。多个 Utility 进程并存时serviceName给出的是类别name给出的是具体服务两个字段互为补充。CPU 使用率cpuCPUUsagecpu是一个CPUUsage对象包含三个字段字段类型说明percentCPUUsagenumber自上次返回该对象的调用以来的 CPU 使用百分比首次调用返回 0cumulativeCPUUsagenumber可选进程启动以来累计使用的 CPU 时间秒idleWakeupsPerSecondnumber自上次调用以来进程空闲时的平均 CPU 唤醒次数首次调用返回 0Windows 上恒为 0几个关键点来自 docs/api/structures/cpu-usage.mdpercentCPUUsage与idleWakeupsPerSecond是平均值而非瞬时采样每次调用开启新的测量区间多个 API 都会返回CPUUsage但各自维护独立的区间process.getCPUUsage()测量其被调用的那个进程只有该进程内的调用才会重置它的区间app.getAppMetrics()测量应用内每个进程按每个进程 ID保存独立区间一次调用会同时重置所有进程因此同一个主进程在同一时刻通过两个 API 报告的percentCPUUsage可能不同如果你的某个依赖也调用了这些函数会在你读取之前开启新区间——此时文档建议使用cumulativeCPUUsage代替用两次读数相减即可得到你所控制区间的使用量读取它仍需调用app.getAppMetrics()或process.getCPUUsage()而这会为其他调用方开启新区间。内存memoryMemoryInfomemory是一个MemoryInfo对象所有统计值以 KB 为单位字段类型平台说明workingSetSizeInteger—当前固定在物理 RAM 中的内存量peakWorkingSetSizeInteger—历史峰值固定在物理 RAM 中的内存量privateBytesInteger可选Windows不被其他进程共享的内存如 JS 堆、HTML 内容源码在此处做了字节到 KB 的换算右移 10 位且privateBytes仅在BUILDFLAG(IS_WIN)保护下写入与文档的平台标注一致。另需注意官方文档未给memory字段标注平台限制但从源码结构看electron_api_app.cc 中的#if !BUILDFLAG(IS_LINUX)守卫表明Linux 构建不会填充该字段。若在 Linux 上需要内存数据建议自行准备降级方案如读取/proc。平台安全字段sandboxed与integrityLevelsandboxedmacOSWindows进程是否被操作系统级沙箱化。macOS 上直接取自进程沙箱状态Windows 上则由完整性级别经ProcessMetric::IsSandboxed(integrity_level)推导见源码integrityLevelWindowsWindows 进程完整性级别取值为untrusted/low/medium/high/unknown。这两个字段在 Linux 上不存在与源码中的平台分支相互印证。字段如何组装源码走读组装逻辑集中在 shell/browser/api/electron_api_app.cc 的App::GetAppMetrics方法中。主进程持有的app_metrics_成员保存原始进程指标数据每次调用遍历它并转换成 V8 对象CPU 字段先从 Chromium 的ProcessMetrics读取累计 CPU 时间若可用则写入cumulativeCPUUsagepercentCPUUsage由平台无关 CPU 使用率除以逻辑处理器数量得出usagePercent / processor_count。这意味着 8 核机器上占满单核的进程会被报告为约 12.5%——可以把它理解为占总 CPU 容量的百分比Windows 特判Windows 未实现空闲唤醒统计源码显式写入 0以避免 Chromiumprocess_metrics.cc的非致命警告——这正是文档中idleWakeupsPerSecond在 Windows 恒为 0的实现原因type与creationTimetype取自content::GetProcessTypeNameInEnglish()的英文名creationTime为进程创建时间调用InMillisecondsFSinceUnixEpoch()的结果与文档距 epoch 毫秒一致serviceName/name均为非空才写入因此某些进程对象上可能完全不存在这两个字段消费方需做m.serviceName ?? -之类的防御性访问内存与沙箱memory子对象仅在非 Linux 平台构建Windows 额外写入integrityLevel与sandboxedmacOS 仅写入sandboxed。实战示例定期采集进程指标结合上述字段下面给出一个可复用的主进程监控实现。要点以pid creationTime为进程键、用cumulativeCPUUsage做差得到自控区间的使用量、聚合workingSetSize得到应用总内存占用KB → MBconst { app } require(electron); // 进程键pid 单独不可靠因为 pid 可能被复用 const makeKey (m) ${m.pid}:${m.creationTime}; const snapshot new Map(); // key - 上一次的 ProcessMetric function collectMetrics() { const metrics app.getAppMetrics(); let totalWorkingSetKB 0; for (const m of metrics) { const key makeKey(m); const prev snapshot.get(key); // 1) 总内存占用KB - MBLinux 上 memory 可能缺失需守卫 if (m.memory) { totalWorkingSetKB m.memory.workingSetSize; } // 2) 自控区间的 CPU 使用量用累计值做差避免被其他调用方干扰 if (m.cpu.cumulativeCPUUsage ! null prev prev.cpu.cumulativeCPUUsage ! null) { const cpuSeconds m.cpu.cumulativeCPUUsage - prev.cpu.cumulativeCPUUsage; console.log( [${m.type}] pid${m.pid} service${m.serviceName ?? -} cpuDelta${cpuSeconds.toFixed(2)}s rss${((m.memory?.workingSetSize ?? 0) / 1024).toFixed(1)}MB ); } // 3) 自上次调用 getAppMetrics() 以来的平均值本次调用会重置区间 console.log([avg] pid${m.pid} percentCPUUsage${m.cpu.percentCPUUsage}); snapshot.set(key, m); } // 清理已退出进程的键避免 Map 无限增长 const liveKeys new Set(metrics.map(makeKey)); for (const k of snapshot.keys()) { if (!liveKeys.has(k)) snapshot.delete(k); } console.log(Total RSS: ${(totalWorkingSetKB / 1024).toFixed(1)} MB); } app.whenReady().then(() { setInterval(collectMetrics, 5000); });两条使用提醒均出自文档percentCPUUsage/idleWakeupsPerSecond是自上次getAppMetrics()调用以来的平均值每 5 秒采集一次意味着区间就是 5 秒若有依赖库也调用该 API会重置你的平均区间长期统计建议以cumulativeCPUUsage差值为准memory字段在 Linux 上可能缺失见上文源码分析务必以if (m.memory)防御。测试套件交叉验证spec/api-app-spec.ts 的getAppMetrics() API小节对ProcessMetric的几乎所有字段做了断言是字段语义的活验证每个条目pid 0、type为非空字符串、creationTime 0cpu必须同时包含percentCPUUsage、cumulativeCPUUsage、idleWakeupsPerSecondmemory.workingSetSize与memory.peakWorkingSetSize须大于 0Utility/GPU类型进程必须有非空serviceNameUtility还必须有nameWindows 上memory.privateBytes大于 0非 Linux 平台sandboxed须为booleanWindows 上integrityLevel须为字符串类型集合macOS 上必须包含GPU所有平台必须包含Browser。测试中按process.platform分支的条件断言与正文讨论的源码平台守卫一一对应可作为验证监控代码输出的现成参照。平台字段速查表字段LinuxmacOSWindowspid/type/creationTime有有有serviceName/name有非空时有非空时有非空时cpu.percentCPUUsage/cumulativeCPUUsage有有有cpu.idleWakeupsPerSecond有有恒为 0memory.workingSetSize/peakWorkingSetSize源码未填充见正文有有memory.privateBytes——有sandboxed—有有由完整性级别推导integrityLevel——有小结ProcessMetric是 Electron 中从主进程读取每个进程资源占用的唯一官方入口。使用它时抓住三件事pid creationTime双键标识、CPU 用量是区间平均且各 API 区间相互独立、memory/sandboxed/integrityLevel存在平台差异且字段可能整体缺失需防御性访问。文档定义process-metric.md、cpu-usage.md、memory-info.md、实现electron_api_app.cc与测试api-app-spec.ts共同构成了这一结构行为的完整证据链。【免费下载链接】electron:electron: Build cross-platform desktop apps with JavaScript, HTML, and CSS项目地址: https://gitcode.com/GitHub_Trending/el/electron创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考