3

I'm having a little trouble monitoring memory usage of an application. I already have some code that gets the process by name.. But there can be multiple processes with the same name. So it will only monitor the first process in the list.. So I'm trying to get it by PID. But I have no code that works.. But here is what I used when I got it by name:

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)
        {

        }
    }

EDIT: I have the PID. But I don't know how to start the monitoring from that.

Stian Tofte
  • 213
  • 6
  • 13
  • Why don't you just install a trial of ANTS Profiler (14 day trial). If you are trying to identify memory issues, it is the one. – Anthony Horne May 01 '14 at 10:58
  • @Anthony Horne Not trying to identify memory issues.. It should monitor a server(game server) memory ussage.. – Stian Tofte May 01 '14 at 10:59
  • I assume you copy/paste did screw up the code here. What is .ProcessName ment to do? – rene May 01 '14 at 11:00
  • @rene It gets the process name.. From my other class. – Stian Tofte May 01 '14 at 11:01
  • Just look more closely `{.ProcessName` is not going to compile... – rene May 01 '14 at 11:03
  • @rene it does.. It runs fine.. And it's monitoring the process just fine.. But my problem is.. That it will be multiple processes with the same name.. That is why i have to find a way to get it by PID. Or else it will monitor the wrong application. – Stian Tofte May 01 '14 at 11:05
  • @rene didn't notice that one. Removed it from my copy paste now. – Stian Tofte May 01 '14 at 11:07
  • Have you looked at http://stackoverflow.com/questions/755919/memory-usage-in-c-sharp using processes instead of the performance counters? – Anthony Horne May 01 '14 at 11:11
  • 1
    @AnthonyHorne Process Explorer is free (this isn't Highlander.) http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx – Jodrell May 01 '14 at 11:25
  • @Jodrell As per Stian noted, it is required to "run / monitor" as part of their application. I do really like the sysinternals apps. They rock and have saved my bacon a few times. – Anthony Horne May 01 '14 at 12:01

2 Answers2

4

I don't understand why you're complicating things. You can easily get the process's memory usage as follows:

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

This property returns the memory used up by pages in the working set in bytes.

Jurgen Camilleri
  • 3,559
  • 20
  • 45
  • I have been testing the `Process` class, and it seems that `Process.WorkingSet64` (as well as the rest of the properties) returns the same value on subsequent calls, so my guess is that it fetches the reading from the moment the object was created. So, it seems that one would have to do a `Process.GetProcessById(pid);` on each iteration... :( Weird but anyway... – user2173353 Oct 07 '16 at 09:48
0

You have many possibilities to constantly observe the memory consuption of the process. One of them is (for example if you do not have UI application) to start a task (using the .NET Task Parallel Library), that continuosly polls the memory consuption. The first step is to get the process (by name or by PID and take the current memory usage. The easiest way to do this is as @Jurgen Camilleri suggested:

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);
    }
}

Using WorkingSet(64) is the closest info to the task manager memory usage (that you can get that simple). The polling code:

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();

If you have a windows forms / WPF application that is running, you could use for example timers (and their callback method, for example the System.Threading.Timer class) instead of task in order to poll the memory usage on some specified interval.

keenthinker
  • 7,645
  • 2
  • 35
  • 45