According to How to use .NET PerformanceCounter to track memory and CPU usage per process? PerformanceCounter
should give me the number of memory usage of a given process.
According to MSDN, Process
instance may also give me more or less the same number.
In order to verify my assumptions, I wrote the following code:
class Program
{
static Process process = Process.GetCurrentProcess();
static PerformanceCounter privateBytesCounter = new PerformanceCounter("Process", "Private Bytes", process.ProcessName);
static PerformanceCounter workingSetCounter = new PerformanceCounter("Process", "Working Set", process.ProcessName);
static void Main(string[] args)
{
GetMeasure();
Console.WriteLine("\nPress enter to allocate great amount of memory");
Console.ReadLine();
int[] arr = new int[10000000];
for (int i = 0; i < arr.Length; i++)
{
arr[i] = i;
}
GetMeasure();
privateBytesCounter.Dispose();
workingSetCounter.Dispose();
Console.ReadKey();
}
private static void GetMeasure()
{
Console.WriteLine("{0,38} {1,20}", "Private bytes", "working set");
Console.WriteLine("process data{0,23} {1,20}", process.PrivateMemorySize64 / 1024, process.WorkingSet64 / 1024);
Console.WriteLine("PerformanceCounter data{0,12} {1,20}", privateBytesCounter.NextValue() / 1024, workingSetCounter.NextValue() / 1024);
}
}
The output looks like
Private bytes working set
process data 22880 17516
PerformanceCounter data 21608 15608
Press enter to allocate great amount of memory
Private bytes working set
process data 22880 17516
PerformanceCounter data 21608 15608
Exactly the same! In the contrast, private bytes shown in Process Explorer increased from 32732 to 63620.
So am I doing something wrong?
To read from a performance counter, create an instance of the PerformanceCounter class, set the CategoryName, CounterName, and, optionally, the InstanceName or MachineName properties, and then call the NextValue method to take a performance counter reading.
In the navigation pane, expand Monitoring Tools, and then choose Performance Monitor. In the console pane toolbar, choose the Add button. In the Add Counters window, in the Select counters from computer drop-down list, choose the computer that is running Business Central Server.
The CPU performance counters are counting the number of instructions, clock ticks and multi counters ticks. They are used to measure the run-time of a c-function. The result is stored in a global variable.
You have to tell your process
instance it should refresh its cached data. Data is not gathered each time you access to a property for performance purposes. You have to manually demand the data update.
private static void GetMeasure()
{
process.Refresh(); // Updates process information
Console.WriteLine("{0,38} {1,20}", "Private bytes", "working set");
Console.WriteLine("process data{0,23} {1,20}", process.PrivateMemorySize64 / 1024, process.WorkingSet64 / 1024);
Console.WriteLine("PerformanceCounter data{0,12} {1,20}", privateBytesCounter.NextValue() / 1024, workingSetCounter.NextValue() / 1024);
}
That's for your process
.
For performance counters, NextValue()
is supposed to retrieve a new fresh data each time, so I can't explain why it doesn't on your machine. On mine it works fine.
EDIT:
With the process.Refresh()
added, here's what I get:
Private bytes working set
process data 25596 22932
PerformanceCounter data 26172 23600
Press enter to allocate great amount of memory
Private bytes working set
process data 65704 61848
PerformanceCounter data 65828 61880
Caution: my memory profiler (.NET Memory Profiler) revealed that Process.Refresh() allocates a significant chunk of memory on a temporary basis, so keep this in mind if you're reading your performance counters on a regular basis by using a timer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With