通过进程ID获取进程并监控内存使用情况

3

我在监控应用程序的内存使用方面遇到了一些问题。我已经编写了一些代码,可以通过名称获取进程。但是可能会有多个具有相同名称的进程。所以它只会监视列表中的第一个进程。因此我尝试通过PID来获取它。但是我没有有效的代码。但是这是我在通过名称获取它时使用的代码:

private void SetMemory()
    {
        PerformanceCounter performanceCounter = new PerformanceCounter
        {
            CategoryName = "Process",
            CounterName = "Working Set",
            InstanceName = MinecraftProcess.Process.ProcessName
        };
        try
        {
            string text = ((uint)performanceCounter.NextValue() / 1024 / 1000).ToString("N0") + " MB";
            MemoryValue.Text = text;
            radProgressBar1.Value1 = ((int)performanceCounter.NextValue() / 1024 / 1000);
        }
        catch (Exception ex)
        {

        }
    }

编辑:我有进程ID。但是我不知道如何从那里开始监视。


@Anthony Horne 不是在尝试识别内存问题... 它应该监控服务器(游戏服务器)的内存使用情况.. - Stian Tofte
我假设你在这里复制/粘贴时弄乱了代码。.ProcessName 的作用是什么? - rene
@rene 它获取进程名称.. 来自我的另一个类。 - Stian Tofte
1
@AnthonyHorne Process Explorer是免费的(这不是《炫耀高手》)。http://technet.microsoft.com/zh-cn/sysinternals/bb896653.aspx - Jodrell
@AnthonyHorne 我会看一下的。 - Stian Tofte
显示剩余6条评论
2个回答

4

我不明白你为什么要把事情变得复杂。你可以按照以下方式轻松获取进程的内存使用情况:

int pid = your pid;
Process toMonitor = Process.GetProcessById(pid);
long memoryUsed = toMonitor.WorkingSet64;

此属性返回工作集中页面使用的内存量(以字节为单位)。


我一直在测试Process类,似乎Process.WorkingSet64(以及其余属性)在后续调用时返回相同的值,因此我的猜测是它从对象创建时就获取了读取。所以,每次迭代都需要对Process.GetProcessById(pid)进行操作... :( 怪异但无论如何... - user2173353

0

您有许多可能性来不断观察进程的内存消耗。其中之一是(例如,如果您没有 UI 应用程序),启动一个 任务(使用 .NET 任务并行库),它会持续地 轮询 内存消耗。第一步是获取进程(按名称或 PID)并获取当前内存使用情况。最简单的方法是按照 @Jurgen Camilleri 的建议执行此操作:

private void checkMemory(Process process)
{
    try
    {           
        if (process != null)
        {
            Console.WriteLine("Memory Usage: {0} MB", process.WorkingSet64 / 1024 / 1024);
        }
    }
    catch (Exception exception)
    {
        Console.WriteLine(exception.Message);
    }
}

使用WorkingSet(64)是最接近任务管理器内存使用情况的信息(这是您可以获得的最简单的信息)。轮询代码:

var cancellationTokenSource = new CancellationTokenSource();
var cancellationToken = cancellationTokenSource.Token;
// take the first firefox instance once; if you know the PID you can use Process.GetProcessById(PID);
var firefox = Process.GetProcessesByName("firefox").FirstOrDefault();
var timer = new System.Threading.Tasks.Task(() =>
{
    cancellationToken.ThrowIfCancellationRequested();
    // poll
    while (true)
    {
        checkMemory(firefox);
        // we want to exit
        if (cancellationToken.IsCancellationRequested)
        {
            cancellationToken.ThrowIfCancellationRequested();
        }
        // give the system some time
        System.Threading.Thread.Sleep(1000);
    }
}, cancellationToken);
// start the polling task
timer.Start();
// poll for 2,5 seconds
System.Threading.Thread.Sleep(2500);
// stop polling
cancellationTokenSource.Cancel();

如果您有一个正在运行的 Windows Forms / WPF 应用程序,您可以使用定时器(以及它们的回调方法,例如 System.Threading.Timer class)来代替任务,以便在某个指定的时间间隔内轮询内存使用情况。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接