PowerShellでメモリ使用量の高いプロセスを調べると、タスクマネージャーを開けないサーバーや複数時刻の記録で役立ちます。ただし「メモリ使用量」にはワーキングセット、プライベートメモリ、仮想メモリなど複数の指標があり、一回の上位一覧だけで異常やメモリリークを断定できません。本記事ではGet-Processで安全にスナップショットを取得し、単位変換、PID照合、時系列、CSV記録、判断時の注意点を解説します。
最初にメモリ不足の症状と範囲を確認する
アプリが重い、ページングが増える、空きメモリが少ない、特定プロセスが増え続けるなど、調査目的を記録します。Windowsが空きメモリをキャッシュへ使うことがあるため、使用率が高いだけでは障害とは限りません。タスクマネージャーのメモリ、コミット、利用可能、ページファイル、イベントログと合わせて判断します。
共有サーバーでは、どのユーザーのプロセスか、業務時間帯か、バックアップやスキャン中かを確認します。高メモリプロセスを即時終了すると未保存データやサービスへ影響します。この記事のコマンドは読み取りを目的とし、Stop-Processなどの終了操作は含めません。必要な場合は別の承認済み手順で行います。
基本のGet-Processをオブジェクトとして扱う
Get-Processは実行中プロセスのオブジェクトを返します。Name、Id、CPU、WorkingSet64、PrivateMemorySize64、VirtualMemorySize64などを利用できますが、プロセスや権限により取得できない値があります。画面表示で省略された列だけを見ず、Get-Process | Get-Memberで利用可能なプロパティを確認します。
PIDであるIdは同じプロセス名が複数動くときの識別に必要です。ただしPIDはプロセス再起動で再利用されるため、記録時刻と開始時刻も可能なら併記します。ブラウザーやTeamsなどは複数プロセス構成が正常であり、個々の値とアプリ全体の合計を目的に応じて使い分けます。
ワーキングセット上位をMB表示する
Get-Process | Sort-Object WorkingSet64 -Descending | Select-Object -First 10 Name,Id,@{Name="WorkingSetMB";Expression={[math]::Round($_.WorkingSet64 / 1MB,1)}}で、物理メモリに現在保持されるワーキングセットの上位10件をMBへ換算できます。1MBはPowerShellの数値サフィックスで、出力単位を列名へ明記します。
ワーキングセットには共有可能なページも含まれ、プロセス間で単純合計すると物理メモリ利用と一致しない場合があります。またOSがメモリ圧力に応じて縮小するため、値は変動します。「このプロセスが専有している量」を知りたい場合はPrivateMemorySize64も確認しますが、それぞれ別の意味を持ちます。
プライベートメモリも別列で比較する
Get-Process | Sort-Object PrivateMemorySize64 -Descending | Select-Object -First 10 Name,Id,@{Name="PrivateMB";Expression={[math]::Round($_.PrivateMemorySize64 / 1MB,1)}}は、他プロセスと共有できない割り当ての手掛かりを示します。ワーキングセットと並べると、物理メモリに常駐中の量とプライベート割り当ての違いを比較できます。
PrivateMemorySize64が大きくても、アプリのキャッシュ、データ処理、仮想マシンなど設計上必要な場合があります。逆に小さくてもシステム全体のメモリ不足は起こり得ます。プロセス値だけでなく、総物理メモリ、利用可能メモリ、コミット上限、ページング、処理量と比較します。製品ごとの推奨値や既知問題も公式資料で確認します。
単一スナップショットではなく時系列で見る
メモリリークを疑う場合は、同じプロセスの値が時間とともに増え続け、処理完了後も戻らないかを確認します。短い検証なら一定間隔でName、Id、WorkingSet64、PrivateMemorySize64、取得時刻を記録します。サンプリング自体が負荷にならない間隔を選び、数秒ごとの大量取得を長期間続けません。
プロセスが再起動するとPIDが変わるため、NameだけでなくIdとStartTimeを記録します。StartTimeは権限により取得できない場合があるので例外を処理します。利用者の操作、ジョブ開始、ファイル読込、会議、バックアップなどの時刻も記録し、メモリ増加が処理量に比例する正常動作か、アイドル後も増える異常かを比較します。
同名プロセスをアプリ単位で集計する
複数プロセスを一つのアプリとして見たい場合はNameでGroup-Objectし、WorkingSet64やPrivateMemorySize64を合計します。ただし同じNameでも別のユーザーや別インストール元のプロセスが含まれる可能性があります。サーバーではSessionIdやUserName相当の情報を追加し、対象ユーザーを混同しないようにします。
集計後の合計はランキングには便利ですが、どの子プロセスが増えているかが見えなくなります。上位アプリを特定したら、個別PID、コマンドライン、親子関係、署名、ファイルパスをProcess Explorerなど正規ツールで確認します。見覚えのない名前を検索結果だけでマルウェアと断定せず、組織のセキュリティ手順へ渡します。
CSVへ記録して比較できる形にする
Get-Process | Select-Object Name,Id,@{Name="WorkingSetMB";Expression={[math]::Round($_.WorkingSet64/1MB,1)}},@{Name="PrivateMB";Expression={[math]::Round($_.PrivateMemorySize64/1MB,1)}} | Export-Csv -LiteralPath "C:\Reports\process-memory.csv" -NoTypeInformation -Encoding utf8のように保存できます。保存先の権限と空き容量を確認します。
一回ごとに同じファイルへ上書きするか、追記するか、時刻別ファイルにするかを決めます。追記では列構成が変わらないようスキーマを固定し、取得時刻列を必ず入れます。プロセス名やパスに機密情報が含まれる可能性があるため、レポートを公開場所へ置かず、保管期限と閲覧権限を設定します。
上位プロセスを見つけた後の判断
上位プロセスが業務アプリなら、利用者数、開いているファイル、処理内容、アドイン、版、稼働時間を確認します。Windowsサービスなら、サービス名、依存関係、役割を確認します。終了して軽くなったことは原因特定ではなく一時対処です。再発するならベンダーログ、クラッシュダンプ、パフォーマンスカウンターなど次の診断へ進みます。
OS全体のメモリが不足している場合は、単一プロセスだけでなく、同時実行数、仮想マシン割当、キャッシュ、ページファイル、物理メモリ、アプリ設計を見直します。ページファイルを無効化したり、サービスを停止したりする大きな変更を推測で行いません。障害兆候がある記憶装置では、負荷試験よりバックアップとデータ保護を優先します。
実務での確認チェックリスト
- Get-ProcessのWorkingSet64とPrivateMemorySize64を別指標として扱う
- NameだけでなくId、取得時刻、可能ならStartTimeを記録する
- MB換算の列名へ単位を明記する
- 一回の上位一覧ではなく処理前後・時系列で比較する
- 高メモリだけでプロセスを強制終了しない
- CSVの保存先、権限、機密情報、保管期限を確認する

コメント