news 2026/9/7 19:18:46

Electron MemoryInfo 结构解析:读懂 app.getAppMetrics() 返回的进程内存指标

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Electron MemoryInfo 结构解析:读懂 app.getAppMetrics() 返回的进程内存指标

Electron MemoryInfo 结构解析:读懂 app.getAppMetrics() 返回的进程内存指标

【免费下载链接】electron:electron: Build cross-platform desktop apps with JavaScript, HTML, and CSS项目地址: https://gitcode.com/GitHub_Trending/el/electron

Electron 应用由多个进程(主进程、渲染进程、GPU、Utility 进程等)组成,定位内存问题首先要拿到每个进程的真实占用数据。MemoryInfo就是 Electron 进程监控体系中最核心的数据结构:它被app.getAppMetrics()返回的 ProcessMetric 对象以memory字段的形态暴露给 JavaScript 层,让开发者无需依赖系统工具即可量化各进程的常驻内存、历史峰值以及 Windows 上的私有内存。读完本篇,你将掌握MemoryInfo各字段的精确语义与单位、三大平台(Windows / macOS / Linux)的实现差异,并能通过源码确认这些数字的采集来源。

MemoryInfo 结构定义

MemoryInfo 官方结构文档定义如下:

  • workingSetSizeInteger— 当前实际驻留物理内存(pinned to physical RAM)的内存量;
  • peakWorkingSetSizeInteger— 历史上曾经驻留物理内存的最大值;
  • privateBytesInteger(可选,Windows 独有)— 不被其他进程共享的内存量,例如 JS 堆或 HTML 内容占用的内存。

注意:所有统计值均以 Kilobytes(KB)为单位。这是该结构最容易被忽略的约束——如果你把数值直接当作字节用于展示或告警阈值,误差会是 1024 倍。

MemoryInfo并非独立使用,它作为 ProcessMetric 的memory字段出现:

  • memoryMemoryInfo - The memory information for the process.

也就是说,每次调用app.getAppMetrics()拿到的ProcessMetric数组中,每一个进程条目都附带一份MemoryInfo

获取 MemoryInfo:app.getAppMetrics() 实战

在主进程中通过app.getAppMetrics()获取全量进程指标,示例如下:

const { app } = require('electron') app.whenReady().then(() => { const metrics = app.getAppMetrics() for (const metric of metrics) { if (metric.type === 'Browser' || metric.type === 'Tab') { console.log( `pid=${metric.pid} type=${metric.type} ` + `workingSetSize=${metric.memory.workingSetSize}KB ` + `peakWorkingSetSize=${metric.memory.peakWorkingSetSize}KB` ) } } })

ProcessMetric.type的取值包括BrowserTabUtilityGPUZygote等(完整列表见 ProcessMetric 文档),配合pidcreationTime可以唯一定位一个进程(pid在进程退出后可能被系统复用,因此文档建议两者结合使用)。

平台实现差异:源码级溯源

三个平台的操作系统接口能力不同,MemoryInfo各字段的可用性与数据来源因此存在明显差异。以下分析均出自仓库源码。

Windows:完整三字段

process_metric.cc 中 Windows 分支调用 Win32 APIGetProcessMemoryInfo,将PROCESS_MEMORY_COUNTERS_EX结构直接映射到三个字段:

  • info.WorkingSetSizeworkingSetSize
  • info.PeakWorkingSetSizepeakWorkingSetSize
  • info.PrivateUsageprivateBytes

这正是文档标注privateBytesWindows 专属的原因:Windows 的任务管理器"专用工作集"即来自PrivateUsage

macOS:无 privateBytes

process_metric.cc 的 macOS 分支通过 Mach 接口task_info(MACH_TASK_BASIC_INFO)采集:

  • info->resident_sizeworkingSetSize
  • info->resident_size_maxpeakWorkingSetSize

Mach 的mach_task_basic_info没有"私有内存"这一概念,因此 macOS 上返回的MemoryInfo只包含前两个字段,privateBytes缺失。

Linux:JS 层从 /proc 读取

Linux 下 C++ 层不提供这两个字段,改由 JavaScript 层补全。app.ts 在process.platform === 'linux'时包装原生getAppMetrics,逐个进程读取/proc/<pid>/status,用正则提取:

  • VmRSS(当前常驻集)→workingSetSize
  • VmHWM(历史最大常驻集,High Water Mark)→peakWorkingSetSize

代码片段(摘自 lib/browser/api/app.ts):

const patternVmRSS = /^VmRSS:\s*(\d+) kB$/m const patternVmHWM = /^VmHWM:\s*(\d+) kB$/m const getProcessMemoryInfo = (pid: number) => { const file = getStatus(pid) // 读取 /proc/<pid>/status return { workingSetSize: getEntry(file, patternVmRSS), peakWorkingSetSize: getEntry(file, patternVmHWM) } }

从源码结构看,Linux 分支同样不产生privateBytes——/proc/<pid>/status中虽无直接对应的"私有内存"字段,Electron 也未在此处合成该值,因此该字段在 Windows 之外均应视为可能缺失的可选值,消费端代码需做防御性处理。

MemoryInfo 与 ProcessMemoryInfo 的区分

Electron 有两套容易混淆的内存 API,注意不要混用:

对比项MemoryInfo(本文主题)ProcessMemoryInfo
来源 APIapp.getAppMetrics()(主进程)process.getProcessMemoryInfo()(process 文档)、webContents.getProcessMemoryInfo()
字段workingSetSize/peakWorkingSetSize/privateBytesresidentSet/private/shared
视角任意进程(按 pid)的操作系统级指标当前(或指定 renderer)进程的 resident / private / shared 拆分
单位KilobytesKilobytes

process.getProcessMemoryInfo()返回的ProcessMemoryInfo走的是 Chromium 的内存插桩路径,底层实现在 electron_api_web_contents.cc:通过memory_instrumentation::MemoryInstrumentation::RequestGlobalDumpForPid请求按 pid 的内存 dump。此外文档特别提示:macOS 下 Chromium 不提供residentSet,因为系统会压缩近期未访问的内存页,private才是更能代表真实用量的字段。做跨 API 对比或监控面板时,应明确每个数字出自哪条采集链路。

验证:测试用例中的断言

仓库测试 spec/api-process-spec.ts 对process.getProcessMemoryInfo()的断言可以佐证内存指标的可靠性预期:residentSet在 Linux / Windows 上大于 0,private大于 0,shared允许为 0。这提示我们在消费MemoryInfo时也应有类似的边界意识:workingSetSize正常情况下应大于 0,若读到 0 往往意味着/proc/<pid>/status读取失败(Linux 分支中getStatus捕获异常后返回空字符串,getEntry会解析为 0)。

小结

  • MemoryInfo的三个字段全部以KB为单位,workingSetSize是"当前物理内存占用",peakWorkingSetSize是"历史峰值",privateBytes仅 Windows 提供,可用于观察 JS 堆、页面内容等不可共享部分;
  • Windows 依赖GetProcessMemoryInfo,macOS 依赖 Machtask_info,Linux 则在 JS 层解析/proc/<pid>/statusVmRSS/VmHWM,三平台字段可用性不完全一致,跨平台代码必须容忍privateBytes缺省;
  • MemoryInfo通过ProcessMetric.memoryapp.getAppMetrics()返回,是构建 Electron 应用进程级内存监控的第一手数据源;需要区分它与ProcessMemoryInfoprocess.getProcessMemoryInfo())这两条不同的采集链路。

【免费下载链接】electron:electron: Build cross-platform desktop apps with JavaScript, HTML, and CSS项目地址: https://gitcode.com/GitHub_Trending/el/electron

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 19:17:58

CSS定位全解:relative、absolute、fixed、sticky

CSS 里的 position&#xff0c;我用坏过无数个布局&#xff0c;也救回来过无数个布局。这玩意儿说到底是 CSS 中最容易“一看就会&#xff0c;一用就废”的属性。网上讲 position 的文章多如牛毛&#xff0c;但大多数都在背文档&#xff0c;真正把 relative、absolute、fixed、…

作者头像 李华
网站建设 2026/9/7 19:17:50

基于Copula的多风场出力相关性分析与场景生成聚类削减

先说结论&#xff1a;这套基于 Copula 函数做多风场出力相关性分析、再配合场景生成与聚类削减的流程&#xff0c;在 MATLAB 里跑通并不复杂&#xff0c;真正难的是每一步的参数选择和结果校验。我实际做完一轮之后最深的感受是——Copula 不是万能药&#xff0c;但只要你把边缘…

作者头像 李华
网站建设 2026/9/7 19:17:45

2.4万亿参数MoE模型部署实战:量化、显存与许可证全解析

谁能想到&#xff0c;有一天“下载模型权重”会变成一件需要先算好半天显存、再等一周硬盘的事。最近大家都在讨论那批刚放出来的开放权重&#xff0c;总参数量到了 2.4 万亿&#xff0c;最小的量化文件也要 397GB。说实话&#xff0c;我第一次看到这个数字也愣了一下——许可证…

作者头像 李华
网站建设 2026/9/7 19:17:40

Kafka Producer源码链路剖析:从send()到Broker确认的异步发送机制

有些Kafka的源码分析文章&#xff0c;上来就贴一堆类名和方法签名&#xff0c;看完除了记住了几个名词&#xff0c;脑子里还是浆糊。我一开始读KafkaProducer的时候也是这个状态&#xff0c;后来踩了几个线上问题回头看&#xff0c;才慢慢把整条链路串起来。这篇文章我不打算把…

作者头像 李华
网站建设 2026/9/7 19:15:43

SEO代码优化实战指南:从HTML标签到核心网页指标

1. 为什么说代码优化是SEO的隐形基石这几年我一直在做网站增长相关的工作,接触了大量“明明内容很用心,排名却死活上不去”的站点。排查到最后,十有八九都出在代码层面。很多人对SEO的理解还停留在“多写文章、多铺关键词、多搞外链”,却忽略了一个更底层的逻辑&#xff1a;搜索…

作者头像 李华