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

如何获取已退出Windows进程的最大内存使用量?

获取已退出Windows进程的最大内存使用量

好问题!我之前处理类似需求的时候试过几个可行的方案,这里分享给你:

方案一:进程运行时实时监控并记录最大值

这是最直接也最可靠的方式——既然进程退出后内存属性不可用,那我们就在它运行的时候定期采样,把最大内存值记录下来。你可以用后台线程或者定时器来做这件事,平衡采样精度和性能。

示例代码:

var startInfo = new ProcessStartInfo("your-app.exe")
{
    RedirectStandardOutput = true,
    RedirectStandardError = true,
    UseShellExecute = false,
    CreateNoWindow = true
};

using var process = Process.Start(startInfo);
if (process == null)
{
    Console.WriteLine("进程启动失败");
    return;
}

long maxMemoryUsage = 0;
var monitorThread = new Thread(() =>
{
    while (!process.HasExited)
    {
        try
        {
            // 这里可以根据需求换PrivateMemorySize64、VirtualMemorySize64等属性
            var currentMemory = process.WorkingSet64;
            if (currentMemory > maxMemoryUsage)
            {
                maxMemoryUsage = currentMemory;
            }
            Thread.Sleep(100); // 调整采样间隔,比如50ms会更精准但占用略高
        }
        catch (InvalidOperationException)
        {
            // 进程可能刚退出,直接跳出循环
            break;
        }
    }
});
monitorThread.Start();

// 等待进程完成
process.WaitForExit();
// 确保监控线程也完成
monitorThread.Join();

// 输出结果
Console.WriteLine($"进程退出代码:{process.ExitCode}");
Console.WriteLine($"最大内存使用量:{maxMemoryUsage / (1024 * 1024)} MB");

方案二:使用Windows性能计数器

Windows性能计数器可以追踪进程的各类内存指标,你可以在进程运行时关联对应的计数器,实时记录最大值。它提供的指标比Process类的属性更丰富,比如私有字节、虚拟内存大小等。

示例代码:

var startInfo = new ProcessStartInfo("your-app.exe")
{
    UseShellExecute = false
};

using var process = Process.Start(startInfo);
if (process == null) return;

// 初始化性能计数器,这里选"Private Bytes"作为监控指标
using var memoryCounter = new PerformanceCounter(
    "Process",
    "Private Bytes",
    process.ProcessName,
    true);

long maxPrivateBytes = 0;
while (!process.HasExited)
{
    var currentBytes = (long)memoryCounter.NextValue();
    if (currentBytes > maxPrivateBytes)
    {
        maxPrivateBytes = currentBytes;
    }
    Thread.Sleep(100);
}

process.WaitForExit();
Console.WriteLine($"最大私有字节数:{maxPrivateBytes / (1024 * 1024)} MB");
Console.WriteLine($"退出代码:{process.ExitCode}");

方案三:通过WMI查询峰值内存

WMI的Win32_Process类提供了PeakWorkingSetSize属性,直接对应进程的峰值内存使用量。不过要注意,进程退出后WMI实例可能会被系统快速回收,所以需要在进程刚退出时立即查询。

示例代码:

using System.Management;

var startInfo = new ProcessStartInfo("your-app.exe");
using var process = Process.Start(startInfo);
if (process == null) return;

process.WaitForExit();

// 进程刚退出时立即查询WMI
var query = new ObjectQuery($"SELECT PeakWorkingSetSize FROM Win32_Process WHERE ProcessId = {process.Id}");
using var searcher = new ManagementObjectSearcher(query);
var results = searcher.Get();

foreach (var obj in results)
{
    var peakMemory = (ulong)obj["PeakWorkingSetSize"];
    Console.WriteLine($"峰值工作集大小:{peakMemory / (1024 * 1024)} MB");
}
Console.WriteLine($"退出代码:{process.ExitCode}");

方案对比

  • 方案一:简单易实现,不需要额外权限,精度可控,是最稳妥的选择。唯一需要注意的是采样间隔的调整,避免遗漏短时间内的内存峰值。
  • 方案二:指标更丰富,但需要熟悉性能计数器的命名规则,且进程退出后计数器实例会被清理,无法事后查询。
  • 方案三:可以直接获取系统记录的峰值,不需要自己采样,但依赖WMI服务,且进程退出后可能查不到数据,稳定性不如前两种。

总的来说,方案一是我最推荐的方式,毕竟进程退出后系统不会主动保留内存使用的历史数据,实时记录是最可靠的办法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:21:30