Get-Processを使う前に、端末がどの実装を呼び、どの対象を読むかを確認してください。PowerShellでプロセスのメモリ使用量を取得する方法の結論は「画面上のmemory目安はWorkingSet64、processが私有的にcommitした量の参考はPrivateMemorySize64として別列で取得します。単発値ではleakを断定せず、IdとStartTimeを固定して時系列を取ります。」。WorkingSet64、PrivateMemorySize64、PagedMemorySize64を区別し、同名複数processを合計する条件を明示する環境で、未確認の変更を避けるための順番を示します。
process instanceをPIDとStartTimeで固定する
プロセスメモリーは、対象のIdとStartTimeを組にして同じプロセスを追跡します。WorkingSet64とPrivateMemorySize64は意味が異なるため、バイト値をMiBへ個別に変換し、一定間隔で複数回記録します。終了・再起動・アクセス拒否を欠測として残し、一回の値だけでメモリーリークと断定しません。
- Get-ProcessでName、Id、StartTimeを確認する
- Get-Memberで利用propertyを確認する
- 同名processを個別表示か合計か決める
- sampling intervalと保存期間を決める
WorkingSetとPrivateMemoryを別metricで表示する
個別processをMiB表示
Get-Process -Name 'notepad' -ErrorAction SilentlyContinue |
Select-Object ProcessName,Id,StartTime,@{n='WorkingSetMiB';e={[math]::Round($_.WorkingSet64/1MB,1)}},@{n='PrivateMiB';e={[math]::Round($_.PrivateMemorySize64/1MB,1)}}
1MBはPowerShellで1048576byteです。表示labelをMiBとします。
上位processを並べる
Get-Process | Sort-Object WorkingSet64 -Descending | Select-Object -First 20 ProcessName,Id,@{n='WSMiB';e={[math]::Round($_.WorkingSet64/1MB,1)}}
取得時点snapshotです。
同名を合計
Get-Process -Name 'chrome' -ErrorAction SilentlyContinue | Group-Object ProcessName |
Select-Object Name,Count,@{n='TotalWSMiB';e={[math]::Round(($_.Group|Measure-Object WorkingSet64 -Sum).Sum/1MB,1)}}
browser multi-processの全instanceを対象とする場合だけ合計します。
上限付き時系列
1..12 | ForEach-Object { Get-Process -Id 1234 -ErrorAction SilentlyContinue | Select-Object @{n='Time';e={Get-Date}},Id,WorkingSet64,PrivateMemorySize64; Start-Sleep 5 }
Idは確認済みに置き換え、process終了を欠測として扱います。
counterと補足比較
Get-Counter '\Process(*)\Working Set - Private' -MaxSamples 1 | Select-Object -ExpandProperty CounterSamples | Sort-Object CookedValue -Descending | Select-Object -First 20 InstanceName,CookedValue
counter instance名の重複・suffixとPID対応を確認します。
同名processの合計と個別値を分ける
取得は読み取りです。高頻度polling、全property展開、長期無制限CSVは負荷とdisk枯渇を招きます。memoryを下げるためprocessを強制終了すると未保存dataが失われるため、owner承認とgraceful終了を優先します。restartが必要なら前状態、session、job、復旧方法を確認します。
上限付き時系列で増減を見る
Working setは現在physical memoryにresidentなpageで共有pageを含み得ます。PrivateMemorySize64は私有memoryの参考ですが、applicationのlogical cacheやGC heapと一致しません。同名process合計は重複shared pageを含み得ます。leak判断には同じinstanceの時間推移、load、GC、commit、system memory pressureを合わせます。
performance counterのinstance名を補助にする
- WorkingSetを全memory使用量とする
- 同名複数processを一件とする
- MBとMiBを混同する
- 単発増加をleakと断定する
- 調査のため強制終了する
process終了を0 byteへ置換しない
Task Managerの同一PID、Performance Monitor、Get-Processを同時刻で比較し、指標名を合わせます。idle/load後の複数sample、process再起動、Id変更を記録します。CSVへ出す場合は時刻、Id、StartTime、単位を必須列にします。
同一instanceのsample数と傾向を検収する
WorkingSet64は物理memory resident量、PrivateMemorySize64はprivate commitで意味が異なります。Id+StartTimeでinstanceを固定し、同名processの合計と個別値を分け、時系列sampleでは終了・再起動を検出します。
PID指定で二つのmemory metricを取得する
$p=Get-Process -Id 1234 -ErrorAction Stop
[pscustomobject]@{Id=$p.Id;StartTime=$p.StartTime;WSMiB=[math]::Round($p.WorkingSet64/1MB,1);PrivateMiB=[math]::Round($p.PrivateMemorySize64/1MB,1);Handles=$p.HandleCount}
process終了をmemory 0として集計しない
- memory sample取得:同一PID+StartTimeのWS/Privateを複数時点で取得し、byteからMiBへ明示変換できる
- 測定中に終了:processなし/途中終了はNoProcess/Exitedとして0 MiBにしない
- process access error:access denied、counter instance名ずれ、sample欠損はPartialとして件数化する
CPU列やWorkingSetのdisplay formatをmemory leakの根拠にしません。同名chrome等を一つのprocessとみなす場合も合計と最大を別列にし、GCやshared pagesを踏まえて長いtrendを確認します。
PID再利用と同名複数processを試す
$samples=1..6 | ForEach-Object { $p=Get-Process -Id 1234 -ErrorAction SilentlyContinue; if($p){[pscustomobject]@{Time=Get-Date;Id=$p.Id;Start=$p.StartTime;WS=$p.WorkingSet64;Private=$p.PrivateMemorySize64}}; Start-Sleep 2 }
$samples | Group-Object Id,Start | Select-Object Name,Count
同名複数、0件、途中終了/再起動、短いspike、継続増加をtestします。Id、StartTime、metric名、byte値、sample interval、欠損理由を保存します。
WorkingSet64とPrivateMemorySize64は異なる概念です。Name合計を個別processのleak判定へ使わず、IdとStartTimeが同じinstanceの複数sampleから傾向を確認します。

コメント