news 2026/10/22 23:38:24

windows_exporter memory collector 深度解析:Windows 内存指标采集原理、完整指标清单与监控告警实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
windows_exporter memory collector 深度解析:Windows 内存指标采集原理、完整指标清单与监控告警实践
  • 可观测性
  • 指标监控

【免费下载链接】windows_exporter

Prometheus exporter for Windows machines

项目地址:https://gitcode.com/gh_mirrors/wi/windows_exporter
点击查看免费下载

本篇以 windows_exporter 的 memory collector 文档为核心,系统讲解该采集器的数据来源(Windows Performance Counters 与GlobalMemoryStatusExAPI)、全部 35 项windows_memory_*指标的含义与类型,并结合仓库源码说明其采集调用链、PromQL 查询示例与告警规则写法。读完后你可以独立完成 Windows 主机的内存用量监控、Commit 告警配置,并能看懂指标背后的 Windows 分页机制语义。

一、memory collector 概览

memory collector 是 windows_exporter 用于暴露系统内存使用情况的采集器,其基本属性如下(与 collector 文档 一致):

属性说明
Metric name prefixmemory(完整指标名带windows_前缀,如windows_memory_available_bytes)
Data sourcePerformance Counters(性能计数器)
Classes无 WMI Class,直接读取Memory性能对象
Enabled by default?是(默认启用)

memory 属于默认启用的采集器之一。从源码 DefaultCollectors 定义 可以确认:

const DefaultCollectors = "cpu,memory,logical_disk,physical_disk,net,os,service,system"

因此只要以默认参数启动 windows_exporter,无需任何额外配置即可采集全部内存指标;如需手动指定采集器列表,也无需为 memory 传任何 Flag(该 collector 无命令行参数,源码 NewWithFlags 直接返回空Collector{},其 Config 为空结构体)。

二、数据来源:两条并行的采集路径

从 memory collector 实现 的Collect方法可以看到,一次采集由两个子过程组成,错误会分别包装后合并返回:

func (c *Collector) Collect(ch chan<- prometheus.Metric, _ time.Duration) error { errs := make([]error, 0) if err := c.collectPDH(ch); err != nil { errs = append(errs, fmt.Errorf("failed collecting memory metrics: %w", err)) } if err := c.collectGlobalMemoryStatus(ch); err != nil { errs = append(errs, fmt.Errorf("failed collecting global memory metrics: %w", err)) } return errors.Join(errs...) }

2.1 路径一:PDH 性能计数器(绝大多数指标)

在Build阶段,采集器通过通用 PDH 框架订阅Memory性能对象的全部实例(_Total):

c.perfDataCollector, err = pdh.NewCollectorperfDataCounterValues), pdh.CounterTypeRaw, "Memory", pdh.InstancesAll)
  • 第 3 个参数"Memory"即 Windows 性能对象Memory(对应 Win32 计数器库中的 PerfOS/Memory);
  • pdh.CounterTypeRaw表示读取 Raw 计数器类型,保证跨采样周期数值可直接累积为 counter 语义;
  • 泛型参数perfDataCounterValues是 types.go 中定义的映射结构体,用perfdatatag 把每个字段与 Windows 计数器名一一绑定,例如:
type perfDataCounterValues struct { AvailableBytes float64 `perfdata:"Available Bytes"` CommitLimit float64 `perfdata:"Commit Limit"` PageFaultsPerSec float64 `perfdata:"Page Faults/sec"` StandbyCacheCoreBytes float64 `perfdata:"Standby Cache Core Bytes"` // ... 共 35 个计数器 }

PDH 框架(见 internal/pdh/collector.go)基于反射解析这些 tag,自动完成计数器句柄的创建、采样与按字段回填,memory collector 本身无需手写任何 Win32 调用。

2.2 路径二:GlobalMemoryStatusEx(3 项全局状态指标)

另外 3 项指标来自 Win32 API,由 collectGlobalMemoryStatus 完成:

memoryStatusEx, err := sysinfoapi.GlobalMemoryStatusEx()

sysinfoapi 通过kernel32.dll的GlobalMemoryStatusEx进程序调用读取MEMORYSTATUSEX结构体,并将 3 个字段映射为 Prometheus 指标:

指标MEMORYSTATUSEX 字段含义
windows_memory_process_memory_limit_bytesUllTotalVirtual调用进程用户态虚拟地址空间大小,取决于进程类型、处理器与系统配置
windows_memory_physical_total_bytesUllTotalPhys操作系统可见的物理内存总量
windows_memory_physical_free_bytesUllAvailPhys立即可重用的物理内存(standby、free、zero 三个页表之和)

注意源码中的指标命名差异:PDH 路径的“可用内存”对应windows_memory_available_bytes(来自Available Bytes计数器),而 API 路径的physical_free_bytes对应AvailPhys。两者语义相近(都包含可回收页),日常使用任一方均可计算内存使用率,官方示例查询采用的是physical_free_bytes。

三、完整指标清单(35 项)

以下为 memory collector 暴露的全部指标,与 collector 文档 保持一致,按功能域分组说明。所有指标均无标签(Labels 为 None)。

3.1 物理内存与可用内存

指标名类型说明
windows_memory_available_bytesgauge可立即分配给进程或系统使用的物理内存,等于 standby(缓存)、free 与 zero 页表之和
windows_memory_physical_free_bytesgauge当前未使用且可立即可用的物理内存字节数(来自GlobalMemoryStatusEx)
windows_memory_physical_total_bytesgauge操作系统可用的物理内存总量。该值不一定等于真实物理内存,而是报告给操作系统的可用量
windows_memory_process_memory_limit_bytesgauge单个进程可分配的最大内存字节数(用户态虚拟地址空间大小)

3.2 文件系统缓存与页表

指标名类型说明
windows_memory_cache_bytesgauge当前文件系统缓存占用的字节数
windows_memory_cache_bytes_peakgauge自系统上次重启以来 CacheBytes 的峰值
windows_memory_cache_faults_totalcounter在文件系统缓存中找不到目标页、需从内存其他位置(软故障)或磁盘(硬故障)取回的故障次数
windows_memory_free_and_zero_page_list_bytesgauge分配给 free/zero 页表的物理内存,不含缓存数据,可立即分配
windows_memory_modified_page_list_bytesgauge分配给 modified 页表的物理内存,含已被修改、需先写回磁盘才能释放的缓存数据
windows_memory_standby_cache_core_bytesgaugecore 优先级 standby 缓存页表占用的物理内存。系统缺少 free/zero 内存时,低优先级 standby 页先被征用
windows_memory_standby_cache_normal_priority_bytesgauge普通优先级 standby 缓存页表占用的物理内存
windows_memory_standby_cache_reserve_bytesgaugereserve 优先级 standby 缓存页表占用的物理内存
windows_memory_standby_cache_lifetime_secondsgauge页驻留于 standby 缓存页表的长期平均时长(秒),数值偏低通常意味着内存压力
windows_memory_system_cache_resident_bytesgauge系统文件缓存中当前驻留并活跃于物理内存的部分

3.3 Commit(提交内存)

指标名类型说明
windows_memory_commit_limit_bytesgauge无需扩展分页文件即可提交的虚拟内存上限(物理内存 + 分页文件容量)
windows_memory_committed_bytesgauge当前已提交的虚拟内存字节数

Commit 接近 limit 时,即使物理内存尚有剩余,新的内存分配也会失败——这是与“物理内存使用率”不同维度的故障模式,mixin 中为此单独立了WindowsMemoryCommitHighUsage告警。

3.4 页故障与分页(Paging)

指标名类型说明
windows_memory_page_faults_totalcounterCPU 处理故障页的总速率(所有页故障之和)
windows_memory_demand_zero_faults_totalcounter用清零页满足的故障次数。清零页是 Windows 的安全特性,防止进程读到此前使用者留下的数据
windows_memory_transition_faults_totalcounter通过回收“正被其他共享进程使用、位于 modified/standby 页表、或正在写回磁盘”的页而无需额外磁盘活动解决的故障数
windows_memory_transition_pages_repurposed_totalcounter过渡缓存页被改作他用的速率(这些页本可留在页缓存中提供软故障加速)
windows_memory_write_copies_totalcounter因写操作触发、通过从物理内存其他位置拷贝页而满足的页故障数(Copy-on-Write)
windows_memory_swap_page_reads_totalcounter磁盘页读取操作次数(一次读多页只计一次)
windows_memory_swap_pages_read_totalcounter所有页读操作中读回的页总数(即使同批读取也逐页计数)
windows_memory_swap_pages_written_totalcounter所有页写操作中写出的页总数
windows_memory_swap_page_operations_totalcounter换页读 + 写的总次数(PagesPerSec 计数器)
windows_memory_swap_page_writes_totalcounter磁盘页写操作次数(一次写多页只计一次)

其中swap_page_reads_total(硬故障读盘)是最能反映“内存压力是否真实导致换页”的指标:物理内存使用率高但页读为 0,说明被占用的主要是可回收的缓存。

3.5 内核内存池(Pool)

指标名类型说明
windows_memory_pool_nonpaged_bytesgaugenon-paged pool 占用字节数。该区域存放不能写盘、只要被分配就必须常驻物理内存的对象
windows_memory_pool_nonpaged_allocs_totalgauge*non-paged pool 的分配调用次数(文档标注为 gauge,对应计数器PoolNonpagedAllocs)
windows_memory_pool_paged_bytesgaugepaged pool 占用字节数
windows_memory_pool_paged_resident_bytesgaugepaged pool 中当前驻留于物理内存且活跃的部分
windows_memory_pool_paged_allocs_totalcounterpaged pool 的分配调用次数(不论每次分配多少空间)

non-paged pool 持续增长而应用工作集没有变化时,通常指向内核驱动内存泄漏——官方 Memory 仪表盘面板的描述即如此提示(见 memory 仪表盘定义:“A steadily growing nonpaged pool usually means a driver leaks memory.”)。

3.6 系统代码与驱动

指标名类型说明
windows_memory_system_code_resident_bytesgauge当前驻留并活跃于物理内存的可分页操作系统代码
windows_memory_system_code_total_bytesgauge已映射进系统虚拟地址空间的可分页 OS 代码总量(Ntoskrnl.exe、Hal.dll、启动驱动与文件系统驱动之和);不含必须常驻物理内存的代码
windows_memory_system_driver_resident_bytesgauge设备驱动占用的可分页物理内存(驱动工作集),是System Driver Total Bytes的组成部分
windows_memory_system_driver_total_bytesgauge设备驱动占用的可分页虚拟内存总量,含物理部分与已换出到磁盘的代码/数据

四、常用 PromQL 查询

文档给出的“查看某实例内存使用率(%)”的示例查询:

100 - 100 * windows_memory_physical_free_bytes{instance="localhost"} / windows_memory_physical_total_bytes

mixin 中基于同一指标组的派生查询(见 lib/queries.libsonnet 与 rules.libsonnet)值得在实际环境直接复用:

# 内存使用率比例(0~1) 1 - windows_memory_available_bytes / windows_memory_physical_total_bytes # 已用物理内存(total - available) windows_memory_physical_total_bytes - windows_memory_available_bytes # Commit 使用比例(0~1) windows_memory_committed_bytes / windows_memory_commit_limit_bytes # 换页操作速率(硬故障信号) rate(windows_memory_swap_page_operations_total[5m]) # 缓存合计(mixin 的 windows:memory_cached:bytes 记录规则) windows_memory_cache_bytes + windows_memory_modified_page_list_bytes + windows_memory_standby_cache_core_bytes + windows_memory_standby_cache_normal_priority_bytes + windows_memory_standby_cache_reserve_bytes

mixin 将上述表达式固化为记录规则(windows:memory_usage:ratio、windows:memory_used:bytes、windows:memory_committed:ratio等),仪表盘与告警统一引用记录规则而不是重复计算,告警规则见 alerts.libsonnet。配套的可视化定义在 memory 仪表盘 中,包含 Physical memory、Commit charge、Paging、Kernel pools and cache 四组面板。

五、告警示例

文档提供了两条可直接使用的告警规则示例:

prometheus.rules

# Alert on hosts that have exhausted all available physical memory - alert: MemoryExhausted expr: windows_memory_physical_free_bytes == 0 for: 10m labels: severity: high annotations: summary: "Host {{ $labels.instance }} is out of memory" description: "{{ $labels.instance }} has exhausted all available physical memory" # Alert on hosts with greater than 90% memory usage - alert: MemoryLow expr: 100 - 100 * windows_memory_physical_free_bytes{instance="localhost"} / windows_memory_physical_total_bytes > 90 for: 10m labels: severity: warning annotations: summary: "Memory usage for host {{ $labels.instance }} is greater than 90%"

两点使用说明:

  1. 示例中{instance="localhost"}需要替换为你实际的实例标签,或使用instance=~"..."形式匹配多台主机;
  2. MemoryExhausted用“free 恒等于 0”判定内存耗尽,语义严格但可能滞后;生产实践中更常见的是按阈值比例告警。

仓库 mixin 提供的等价生产级告警(阈值可通过配置调整,默认 90%,持续 15 分钟):

alert( 'WindowsMemoryHighUsage', q.metric('windows:memory_usage:ratio') + ' * 100 > %s' % c.memoryHighUsageThreshold, '15m', 'warning', 'Windows memory usage is high', ... ), alert( 'WindowsMemoryCommitHighUsage', q.metric('windows:memory_committed:ratio') + ' * 100 > %s' % c.memoryCommitHighUsageThreshold, '15m', 'warning', 'Windows memory commit usage is high', ... ),

两条告警分别对应两份 Runbook,可直接作为处置参考:

  • WindowsMemoryHighUsage 处置手册:按“确认使用率比例 → 检查换页速率与 Commit 比例 → 资源监视器查工作集/硬故障 → 检查内核 pool 是否增长”的顺序排查,强调“高使用率比例本身不等于系统正在大量换页”;
  • WindowsMemoryCommitHighUsage 处置手册:Commit 告警时即使物理内存仍有剩余,系统也可能拒绝新的内存提交导致应用失败,手册给出了检查分页文件的 PowerShell 命令(Get-CimInstance Win32_PageFileUsage等),并说明调整分页文件会影响 Commit 上限但不增加物理内存。

六、验证与测试

memory collector 的行为由 memory_test.go 覆盖:TestCollector通过testutils.TestCollector在 Windows 环境完成一次真实采集,断言指标命名、类型与一致性;BenchmarkCollector提供采集耗时的基准测试。该测试文件带//go:build windows约束,只能在 Windows 上运行,与整个 exporter 的构建目标一致。

七、小结

  • memory collector 默认启用、无配置项,数据来源为 PDHMemory性能对象(CounterTypeRaw、全实例订阅)+GlobalMemoryStatusExAPI,两条路径分别产出 32 项与 3 项指标;
  • 指标分五类语义域:物理内存/可用内存、缓存与页表、Commit、页故障与分页、内核池与系统代码,排查“内存压力”时应组合使用(如高使用率 +rate(windows_memory_swap_page_reads_total)判断真实换页);
  • 告警建议同时覆盖“物理内存使用率”与“Commit 比例”两个维度,并参考仓库 mixin 的记录规则与 Runbook 落地为完整监控方案。
  • 可观测性
  • 指标监控

【免费下载链接】windows_exporter

Prometheus exporter for Windows machines

项目地址:https://gitcode.com/gh_mirrors/wi/windows_exporter
点击查看免费下载

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

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

coreboot 模块定制机制解析:用 __weak 弱符号实现静态钩子

固件嵌入式操作系统驱动开发 【免费下载链接】coreboot Read-only mirror of https://review.coreboot.org/coreboot.git. Synced every hour. We dont handle Pull Requests. 项目地址&#xff1a; https://gitcode.com/gh_mirrors/co/coreboot 点击查看 免费下载 本文基于 c…

作者头像 李华
网站建设 2026/10/23 16:01:11

VB.NET WinForms全局异常捕获三层架构与数据保全实战

简介&#xff1a;本资源是一份面向VB.NET初学者与中级开发者的全局异常处理实践方案&#xff0c;聚焦Windows Forms桌面应用中未捕获错误的统一拦截与优雅降级&#xff0c;解决程序因未处理异常而崩溃、日志缺失、用户体验差等典型问题。压缩包共34个文件&#xff0c;涵盖9个核…

作者头像 李华
网站建设 2026/10/22 17:00:21

台风烧录器实战:内存SPD读写与DDR5避坑指南

1. 台风烧录器到底是什么&#xff1a;从内存条SPD说起很多刚接触内存超频或者折腾内存条的朋友&#xff0c;第一次听到“台风烧录器”这个名字&#xff0c;大概率会一头雾水——这玩意儿跟气象灾害有什么关系&#xff1f;其实它跟台风半毛钱关系都没有&#xff0c;纯粹是软件作…

作者头像 李华
网站建设 2026/10/21 1:30:15

让 AI 少读一点:谁来决定删掉哪些信息

如果要预测一位 F1 车手下一场比赛能否完赛&#xff0c;可以参考的数据很多&#xff1a;过往赛果、积分、排位成绩&#xff0c;以及车队相关记录。这些数据通常分散在关系型数据库的不同表里&#xff0c;依靠外键关联。 面对模型有限的输入空间&#xff0c;哪些关联记录值得优…

作者头像 李华
网站建设 2026/10/22 1:25:07

STC15单片机驱动OLED黑屏排查:IO模式、I²C地址与时序三要素

简介&#xff1a;本资源是一套面向嵌入式初学者与单片机开发者的STC15单片机OLED显示驱动实战代码&#xff0c;聚焦于通过软件模拟IC协议实现SSD1306/SH1106类OLED模块的稳定显示&#xff0c;解决8051架构下无硬件IC外设时的外设驱动难题。压缩包共32个文件&#xff0c;含4个核…

作者头像 李华