I want to get my application pool's memory usage using Process class. This is my code so far:
ServerManager serverManager = new ServerManager();
ApplicationPoolCollection applicationPoolCollection = serverManager.ApplicationPools;
Process process = Process.GetProcessById(applicationPoolCollection.Where(p => p.Name == "mywebsite.com").First().WorkerProcesses[0].ProcessId);
I can get Process class but how do I know what is the amount of RAM it is using currently? I do see properties like PagedMemorySize64 and NonpagedSystemMemorySize64. Which one would give me the correct RAM that it is occupying at the moment?
I cannot use PerformanceCounter like so:
PerformanceCounter performanceCounter = new PerformanceCounter();
performanceCounter.CategoryName = "Process";
performanceCounter.CounterName = "Working Set";
performanceCounter.InstanceName = process.ProcessName;
Console.WriteLine(((uint)performanceCounter.NextValue() / 1024).ToString("N0"));
The reason being ProcessName would return w3p and therefore PerformanceCounter would write the total IIS RAM usage in Console which is not what I want.
I just need the application pool's RAM usage. Therefore I think my answer lies in Process class and not PerformanceCounter
Any help is appreciated.
If you need simply amount of ram visible to the process, which means amount of ram assigned to the process, but not necessary that every single bit of it is actually used by the process, you can use: WorkingSet. (Choose appropriate version for your .net)
Just invite your attention on the fact, that there is much more into process memory diagnostics, in case you might be concerned about allocated Virtual Memory, Commited Memory, Mapped Files and whatnot.
Related
I am currently having two PerformanceCounters that are creating issues when my Windows Forms application is to be started.
The PerformanceCounters are created in the designer class of a UserControl that is initiated when the application starts. The counters, called performanceCounterMemory and performanceCounterProTime, are created to be able to give the user a real time feedback of the currently used RAM memory and process time (percentage). They are created with the following lines in the designer class
this.performanceCounterMemory = new System.Diagnostics.PerformanceCounter();
this.performanceCounterProTime = new System.Diagnostics.PerformanceCounter();
((System.ComponentModel.ISupportInitialize)(this.performanceCounterMemory)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.performanceCounterProTime)).BeginInit();
this.performanceCounterMemory.CategoryName = "Memory";
this.performanceCounterMemory.CounterName = "% used dedicated byte";
this.performanceCounterProTime.CategoryName = "Processor";
this.performanceCounterProTime.CounterName = "% Processor Time";
this.performanceCounterProTime.InstanceName = "_Total";
((System.ComponentModel.ISupportInitialize)(this.performanceCounterMemory)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.performanceCounterProTime)).EndInit();
For reasons unknown the calls to the last two lines, the EndInit() calls, for both counters are really slow (10+ seconds) making the application very slow to start.
Why is this? What is the purpose of the EndInit calls and is it possible to make it faster?
To be able to use the counters the following two references are added by the lines
using System.Management.Instrumentation;
using System.Management;
The machine processor is: Intel(R) Core(TM) i7-3770 CPU # 3.40GHz
long memory = GC.GetTotalMemory(true);
You can use the following function (the true parameter tells GC to build first)
This is for RAM, I don't really understand, maybe it will help)
I have the following code to launch and monitor a process:
Process process = new Process();
process.StartInfo.FileName = "foo.exe";
long maxMemoryUsage = 0;
process.Start()
while(!process.HasExited)
{
maxMemoryUsage = Math.Max(maxMemoryUsage, process.PrivateMemorySize64);
}
After using this code to run a large application that, according to the task manager used 328 MB at its peak (Memory "Private Working Set"). The value of maxMemoryUsage, and the value of process.PeakPagedMemorySize64 is 364544. According to MSDN this value should be interpreted as bytes, meaning it is a little over 300KB, a factor thousand away from the expected value. The other process.Peak...Memory properties also report extremely low values (all under a megabyte, except for PeakVirtualMemorySize64 which is 4MB which I think is the minimum value for this field).
I've tried launching different applications (C# and C++ based of which I have the source code) which I know to use very little or a lot of memory and the memory values where always very close to the values seen with this process. Apparently I'm doing something completely wrong.
So my question is: How can I measure the maximum memory usage of a process which I spawned from my C# application. (Note that I don't need to have the value ealtime as long as I know its value after the program exited, I also don't need it super precise as I don't care if it was 27.04MB or 30MB, but I do care if it was 30MB or 100MB).
Edit: here is a full reproducable test case
class Program
{
static void Main(string[] args)
{
Process process = new Process();
process.StartInfo.FileName = #"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\devenv.exe";
long maxMemoryUsage = 0;
process.Start();
while(!process.HasExited)
{
maxMemoryUsage = Math.Max(maxMemoryUsage, process.PagedMemorySize64);
}
Console.Out.WriteLine("Memory used: " + (maxMemoryUsage / 1024.0) / 1024.0 + "MB");
Console.ReadLine();
}
}
According to the task manager Visual Studio uses 103MB. After closing Visual Studio the program reports 0.3984375MB.
Process class is heavily cached. You'll get only cached result, no matter how many times you read some property unless you throw a call to Refresh method. You need to call Process.Refresh to get the non cached result.
To quote from msdn
When a Process component is associated with a process resource, the
property values of the Process are immediately populated according to
the status of the associated process. If the information about the
associated process subsequently changes, those changes are not
reflected in the Process component's cached values. The Process
component is a snapshot of the process resource at the time they are
associated. To view the current values for the associated process,
call the Refresh method.
So, your code will become:
while(!process.HasExited)
{
process.Refresh();
maxMemoryUsage = Math.Max(maxMemoryUsage, process.PrivateMemorySize64);
}
Also you may consider looking at process.PeakXXX properties, that will help you I suppose.
I'm writing an application runner on Windows which can limit processor user time and virtual memory for the application it will run. Idea is to have following:
runner.exe mem_limit_in_MB time_limit_in_sec command.exe command_arguments ...
My investigation lead me to Windows Job Objects API and since I'm trying to do all that from C#, I found JobObjectWrapper to help me.
The main part of the code if following:
using (JobObject jo = new JobObject())
{
// Time
jo.Limits.PerProcessUserTimeLimit = TimeSpan.FromMilliseconds(limitTime);
jo.Events.OnEndOfProcessTime += new jobEventHandler<EndOfProcessTimeEventArgs>(Events_OnEndOfProcessTime);
// Memory
jo.Limits.ProcessMemoryLimit = new IntPtr(limitMemory);
jo.Events.OnProcessMemoryLimit += new jobEventHandler<ProcessMemoryLimitEventArgs>(Events_OnProcessMemoryLimit);
// Process
ProcessStartInfo psi = new ProcessStartInfo(command, arguments);
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
jo.Limits.IsChildProcessBreakAway = false;
Process p = jo.CreateProcessSecured(psi);
p.WaitForExit();
}
Now, the problem is that it seams that Events_OnEndOfProcessTime is not called timely. If I set 0.5 sec limit for an app that takes several minutes, depending on the run application is once terminated after 0.5 sec and sometimes after 4 sec. Why is this happening? I cannot find any reference if Job Objects are checking limits periodically or in real-time.
My question is two-fold:
- Does anyone know about already developed code that does what I need?
- Does anyone know if Job Objects are executed periodically or in real time?
Thanks in advance...
PerProcessUserTimeLimit specifies the amount of user-mode time is granted to the process.
"The system periodically checks to determine whether each process associated with the job has accumulated more user-mode time than the set limit. If it has, the process is terminated." (MSDN)
Consequently it depends on your application, particulary on how effient it is burning user-mode time. Ending a process with PerProcessUserTimeLimit = 0.5 after 0.5 sec. means that it has used ~100% cpu (user-mode) during that time.
... if Job Objects are executed periodically or in real time? Periodically, as stated above.
I would like to write a small piece of program that launches threads, consumes available RAM memory in a linear fashion, until a certain level, and stops (ideally, pauses until "enough" memory is freed and continues creating threads after that, and so on.)
I tried the following, but the list.Add(new byte[]) requires contiguous RAM space and drops an OutOfMemoryException, which is NOT what I am trying to simulate.
EDIT :
I have a multi-threaded memory-hungry application that eats up a whole bunch of RAM GB's. All I want is to isolate/reproduce that situation in "Lab conditions" to tackle it, i.e write an adaptive mem-monitoring / thread-limiter draft. I am using x64 OS an x64 Platform.
To make it clear : The result I want to see is the Task Manager Memory Monitor going up straight due to the program.
static void Main(string[] args)
{
ComputerInfo ci = new ComputerInfo();
D("TOTAL PHYSICAL MEMORY : " + Math.Round(ci.TotalPhysicalMemory / Math.Pow(10,9),3) +" GB");
//########### Fill Memory ###############
var list = new List<byte[]>();
Thread FillMem= new Thread(delegate()
{
while (Process.GetCurrentProcess().PrivateMemorySize64 < MAX_MEM_LEVEL)
{
list.Add(new byte[1024 * 10000]); //<- I Need to change this
Thread.Sleep(100);
}
});
FillMem.Start();
//########### Show used Memory ###############
Thread MonitorMem = new Thread(delegate()
{
while (true)
{
D("PROCESS MEMORY : " + Math.Round(Process.GetCurrentProcess().PrivateMemorySize64 / Math.Pow(10, 6), 3) + " MB");
Thread.Sleep(1000);
}
});
MonitorMem.Start();
Console.Read();
}
The question is still quite confusing; it is not clear to me what you are trying to do here and why.
If you genuinely want to be consuming physical memory -- that is, telling the operating system no, really do not use this portion of the physical RAM chip that is installed in the machine for anything other than what I say -- then I would probably use the aptly-named AllocateUserPhysicalPages function from unmanaged code.
That will then reduce the amount of physical memory that is available for other uses, forcing more virtual memory pages to go out to the page file.
Other than making all the programs running on your machine a whole lot slower, I'm not sure what you intend to accomplish by this. Can you clarify?
The thing is that with C# you can not grow more then approximately 1.2 GB of RAM on 32 bit .NET framework. You can have even 8GB of RAM on your 64 bit machine, but if the process you run was compiled for 32bit architecture, it will lead to OutOfMemoryException as soon as it reaches approx 1.2GB.
For this kind of testing I would suggest choosing other type of languages/frameworks.
EDIT
A good link on subject:
is-there-a-memory-limit-for-a-single-net-process
If the problem that you're running into is that your process is running out of virtual memory space before the hardware is running out of physical memory space then you could just spin up a number (5 maybe?) processing with your code (and something to stop them at say 1-2 GB so they don't OOM themselves). It's probably not as good of a solution as a unmanaged call to allocate memory, but it would be easy enough to do.
how to detect cpuusage and ram usage of a remote host using c#??
You could use the C# PerformanceCounter class to get this done. It's relatively simple to create a read-only counter:
PerformanceCounter cpuCounter = new PerformanceCounter(category, counter, instance, machine)
The documentation is available here: http://msdn.microsoft.com/en-us/library/9ffskxdc(v=VS.90).aspx
I'm not 100% sure that these are the exact values you want, but these may work:
CPU:
category = Processor
counter = % Processor Time
instance = _Total
RAM:
category = Memory
counter = Available MBytes
instance = (use String.Empty)
Performance Counters can be very tricky if you want your app to work on all modern MS OSs. Things get even more complicated if you want your app to run as regular (non-admin) user.
But that should get you started.
-- Dan