简体   繁体   中英

Get Memory (Private Working Set) of Process

My problem is what i am getting for WorkingSet is very different than Task manager Memory (Private Working Set). I have tried various solutions written on NET but the values are far too away from matching. Kindly help me get Memory (Private Working Set) from task manager.

script += string.Format(@"$Processes = Get-Process -ComputerName {0} | Sort-Object WorkingSet -desc | Select-Object;", remoteMachineName);
script += @"$ProcessArray= @();";
script += @"foreach ($process in $Processes) {";
script += @"$ProcessName = $process.ProcessName;";
script += @"$ProcessSize = $process.WorkingSet/1KB;";
script += @"$objAverage = New-Object System.Object;";
script += @"$objAverage | Add-Member -type NoteProperty -name Name -value $ProcessName;";
script += @"$objAverage | Add-Member -type NoteProperty -name Memory -value $ProcessSize;";
script += @"$ProcessArray +=$objAverage; }; ";

What is shown in Process Manager as Memory (Private Working Set) is the value of the performance counter \\Process\\working Set - Private .

You can retrieve this value with:

$ProcessPrivateSet = Get-Counter "\Process(instancename)\Working Set - Private"
$WSPrivateKiloBytes = $ProcessPrivateSet.CounterSamples[0].CookedValue / 1KB

$WSPrivateKiloBytes is now the same value as what you see in Process Manager.


The problem with retrieving this value for a distinct process is that performance counters name process instances by process name + instance count, rather than by process ID.

So, if you launch 1 instance of a Java application, you may retrieve the counter for the java.exe process, like so:

Get-Counter "\Process(java)\Working Set - Private"

Now, if you launch another one, you'll need to reference that one like this:

Get-Counter "\Process(java#1)\Working Set - Private"

and so on and on.

You can change this behavior by setting the ProcessNameFormat for performance counter objects on the local system like this:

$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\PerfProc\Performance\"
Set-ItemProperty $RegPath -Name ProcessNameFormat -Value 2 -Type DWord

A value of 2 means "include process ID in instance names", a value of 1 (default) would mean "use an instance counter" (like shown above).

The new format will be processname_id


After changing the ProcessNameFormat , you can now retrieve performance counters for a specific Process ID, like so:

$javap = Get-Process -Name java | Select -First 1
Get-Counter "\Process(java_$($javap.Id))\"

Since you now have a distinct correlation between Get-Process output and the performance counters, you can now retrieve the "Private Working Set" value for each process, with a single Select-Object statement using a calculated property:

Get-Process java | Select Name,Id,@{Name="WSPrivate(KB)";Expression = {(Get-Counter "\Process($($_.Name)_$($_.Id))\Working Set - Private").CounterSamples[0].CookedValue / 1KB}}

It will take some time to retrieve each individual counter sample, so if you plan on doing this often or for a large set of processes, you might want to use a wildcard ( * ) and retrieve \\Process(*)\\Working Set - Private and then look at the InstanceName in each entry in CounterSamples

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM