我的问题是我得到的WorkingSet与任务管理器内存(私人工作集)非常不同。我已经尝试过在NET上编写的各种解决方案但是这些值远远没有匹配。请帮助我从任务管理器获取内存(私人工作集)。
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; }; ";
答案 0 :(得分:1)
流程管理器中显示的内容内存(私人工作集)是性能计数器\Process\working Set - Private
的值。
您可以使用以下方法检索此值:
$ProcessPrivateSet = Get-Counter "\Process(instancename)\Working Set - Private"
$WSPrivateKiloBytes = $ProcessPrivateSet.CounterSamples[0].CookedValue / 1KB
$WSPrivateKiloBytes
现在与您在Process Manager中看到的值相同。
为不同进程检索此值的问题是性能计数器按进程名称+实例计数而不是进程ID来命名流程实例。
因此,如果启动1个Java应用程序实例,您可以检索java.exe
进程的计数器,如下所示:
Get-Counter "\Process(java)\Working Set - Private"
现在,如果你推出另一个,你需要像这样引用那个:
Get-Counter "\Process(java#1)\Working Set - Private"
依此类推。
您可以通过在本地系统上为性能计数器对象设置ProcessNameFormat
来更改此行为,如下所示:
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\PerfProc\Performance\"
Set-ItemProperty $RegPath -Name ProcessNameFormat -Value 2 -Type DWord
值为2意味着"在实例名称中包含进程ID",值为1(默认值)意味着"使用实例计数器" (如上所示)。
新格式为processname_id
更改ProcessNameFormat
后,您现在可以检索特定进程ID的性能计数器,如下所示:
$javap = Get-Process -Name java | Select -First 1
Get-Counter "\Process(java_$($javap.Id))\"
由于您现在在Get-Process
输出和性能计数器之间存在明显的相关性,因此您现在可以检索"私人工作集"每个进程的值,使用计算属性的单个Select-Object
语句:
Get-Process java | Select Name,Id,@{Name="WSPrivate(KB)";Expression = {(Get-Counter "\Process($($_.Name)_$($_.Id))\Working Set - Private").CounterSamples[0].CookedValue / 1KB}}
将花费一些时间来检索每个单独的计数器示例,因此如果您计划经常执行此操作或执行大量进程,则可能需要使用通配符({{1} }并检索*
,然后查看\Process(*)\Working Set - Private
InstanceName