You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows下快速运行程序的峰值内存占用测量方法问询

在Windows PowerShell中测量短耗时程序的峰值内存占用

需求背景

  • 需要测量运行时间极短(<1秒)的Windows程序的峰值内存占用,资源监视器无法捕捉该数据
  • 要对比同一份代码经cl、clang、gcc(Windows下)编译后的内存使用表现
  • 希望找到类似Linux下/usr/bin/time -v ./test的工具,能直接返回Maximum resident set size这类指标

已尝试方案及问题

我试过用两个PowerShell脚本包装目标程序,但无法正确获取内存数据:

test.ps1(包装目标程序)

# 设置应用程序路径
$applicationPath = ".\test.exe"

# 设置延迟时间(秒)
$delayInSeconds = 10

# 等待指定延迟,方便手动设置监控
Start-Sleep -Seconds $delayInSeconds

# 启动目标程序
Start-Process -FilePath $applicationPath -PassThru

# 再次等待,保留测量窗口
Start-Sleep -Seconds $delayInSeconds

bench.ps1(监控脚本)

Write-Host "启动基准测试"
# 启动test.ps1子进程并获取PID
$processId = Start-Process -FilePath "powershell.exe" -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File .\test.ps1" -PassThru
$id = $processId.id
Write-Host "进程ID: $id"

# 设置等待时间
$delayInSeconds = 15
Start-Sleep -Seconds $delayInSeconds

# 读取峰值内存(工作集)
$peakMemoryUsage = (Get-Process -Id $id).PeakWorkingSet64 / 1MB

# 输出结果
Write-Host "进程ID: $processId"
Write-Host "峰值内存占用: ${peakMemoryUsage} MB"

遇到的问题

无论修改test.exe中的内存分配量(比如添加无优化的大内存分配代码:std::vector<std::string> v(10000000,"Very long string to allocate at least something"); std::cout << v.back() << '\n';),测量出的内存值始终不变。推测是因为Start-Process会在独立进程中启动test.exe,导致监控的是powershell子进程而非目标程序的内存。

另外,也考虑过在test.exe中添加暂停逻辑,但希望找到无需修改目标程序的解决方案。

可行解决方案

方案1:PowerShell直接运行并监控(无嵌套脚本)

直接在脚本中启动目标程序并等待其退出,同时跟踪进程的峰值内存,避免嵌套进程导致的监控对象错误:

$targetExe = ".\test.exe"
# 启动进程并保留进程对象
$proc = Start-Process -FilePath $targetExe -NoNewWindow -PassThru
# 等待进程完全退出
Wait-Process -Id $proc.Id
# 获取峰值内存并转换为MB
$peakMemMB = $proc.PeakWorkingSet64 / 1MB
Write-Host "目标程序: $targetExe"
Write-Host "峰值内存占用: $peakMemMB MB"

方案2:使用Windows原生工具timeit.exe

Windows SDK自带的timeit.exe可以直接测量程序的运行时间和内存使用,用法类似Linux的time命令,输出包含Peak Working Set(峰值工作集)指标:

timeit.exe .\test.exe

如果找不到该工具,可通过安装Windows SDK获取,或从已安装的VS目录中查找(通常路径类似C:\Program Files (x86)\Windows Kits\10\bin\<版本>\x64\timeit.exe)。

方案3:性能计数器实时监控

通过Get-Counter实时跟踪进程内存,确保捕捉到短耗时程序的峰值:

$targetExe = ".\test.exe"
# 启动进程
$proc = Start-Process -FilePath $targetExe -NoNewWindow -PassThru
# 定义跟踪工作集的性能计数器
$counter = Get-Counter "\Process($($proc.ProcessName))\Working Set"
$peakMem = 0
# 循环监控直到进程退出
while (!$proc.HasExited) {
    $current = ($counter.NextCounter().CounterSamples | Select-Object -ExpandProperty CookedValue)
    if ($current -gt $peakMem) { $peakMem = $current }
    Start-Sleep -Milliseconds 10
}
# 最后再获取一次,确保不遗漏退出前的最大值
$finalPeak = ($counter.NextCounter().CounterSamples | Select-Object -ExpandProperty CookedValue)
if ($finalPeak -gt $peakMem) { $peakMem = $finalPeak }
$peakMemMB = $peakMem / 1MB
Write-Host "峰值内存占用: $peakMemMB MB"

方案4:手动暂停验证(适合临时测试)

用Sysinternals的pssuspend工具临时暂停程序,方便手动在资源监视器中查看:

  1. 用包装脚本启动test.exe前先等待几秒
  2. 等待期间执行pssuspend test.exe暂停目标进程
  3. 查看内存数据后,执行pssuspend -r test.exe恢复进程
    此方法适合手动验证,自动化测试推荐前三种方案。

内容的提问来源于stack exchange,提问作者Oersted

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 17:22:09