pmapコマンドでLinuxプロセスのメモリマップを確認する方法|メモリリーク調査とOOM対策の実践手順

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Linuxtips, Linuxトラブルシューティング > pmapコマンドでLinuxプロセスのメモリマップを確認する方法|メモリリーク調査とOOM対策の実践手順
「メモリ使用量が増え続けているのに、どのプロセスが原因か特定できない」「OOMキラーが頻発しているが、何がメモリを食っているのか分からない」——サーバー管理でこうした場面に遭遇したことはないでしょうか?

freetopでシステム全体・プロセス合計のメモリは見えますが、「そのプロセスのどの領域(コード・ヒープ・共有ライブラリ・スタック)がどれだけ使っているか」は分かりません。pmapコマンドを使うと、プロセスの仮想メモリマップを領域別に確認でき、メモリリークの兆候の早期発見やOOMキラー発動前の肥大化プロセスの特定に役立てることができます。

この記事では、pmapコマンドの基本から、メモリリーク調査・OOM対策への実践的な活用パターンまでを解説します。RHEL 9.4 / Ubuntu 24.04 LTSで動作確認済みです。

この記事のポイント

・pmap PID でプロセスの仮想メモリを領域ごとに確認できる
・-x オプションで各マッピングのKbytes・RSS・Dirtyを表示できる
・タイミングをずらして2回実行し差分を見るとメモリリークの兆候を掴める
・RSS合計がOOMキラー発動判断の指標になり、事前の予防的監視に使える


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

なぜpmapが必要なのか?(free・topとの違い)

Linuxのプロセスは起動時にカーネルから「仮想アドレス空間」を割り当てられます。この空間は用途ごとに複数の領域に分かれています。

コードセグメント: 実行バイナリのプログラムコード(r-x--フラグ)
共有ライブラリ: libcやlibpthreadなど複数プロセスで共用される.soファイル
ヒープ: malloc()で動的確保される領域。メモリリークが起きやすい場所
スタック: 関数呼び出しの引数・局所変数([stack]として表示)
匿名マッピング: mmap()で確保されるファイルと紐付かない領域([anon])

free -hはシステム全体のメモリ使用量を、toppsは各プロセスの合計RSSを表示しますが、どの領域がどれだけ使っているかは分かりません。pmapを使えば「ヒープが異常に膨らんでいる」「特定の.soファイルが大量にロードされている」といった問題の糸口を即座に掴めます。

pmapの基本的な使い方

1. プロセスのメモリマップを確認する

pmapにプロセスID(PID)を渡すだけです。PIDはps aux | grep コマンド名 | grep -v grepまたはpgrepで確認できます。

# 書式 pmap PID # PIDを確認してからpmapを実行する例 ps aux | grep nginx | grep -v grep pmap 18234

以下はRHEL 9.4の検証サーバー(svr01)でnginxワーカープロセスに実行した結果です。

[root@svr01 ~]# pmap 18234 18234: nginx: worker process 0000559bc4f00000 4K r---- nginx 0000559bc4f01000 796K r-x-- nginx 0000559bc4fc8000 224K r---- nginx 0000559bc5000000 20K rw--- nginx 0000559bc5005000 52K rw--- [ anon ] 0000559bc6d93000 1536K rw--- [ heap ] 00007fa1b8000000 132K rw--- [ anon ] 00007fa1b8021000 65404K ----- [ anon ] 00007fa1bc000000 132K rw--- [ anon ] 00007fb2c6400000 4096K rw--- [ anon ] 00007fb2c8000000 5164K rw--- libcrypto.so.3.0.7 00007ffe87b4a000 132K rw--- [ stack ] total 106700K

各列の意味:
先頭アドレス: 各マッピングの開始仮想アドレス
サイズ(K): 仮想メモリ上の割り当てサイズ(予約済みで実際に使っているとは限らない)
rwx フラグ: r=読み取り可、w=書き込み可、x=実行可能
名前: バイナリ名・ライブラリ名・[heap]・[stack]・[anon]のいずれか
total: 仮想メモリの合計。実メモリ使用量は次の-xオプションで確認する

2. 詳細情報を表示する(-x オプション)

-x(Extended)オプションを付けると、各マッピングの実メモリ使用量(RSS)と変更済みページ数(Dirty)も表示されます。メモリリーク調査では-xが基本です。

pmap -x PID # 例: nginxワーカープロセス [root@svr01 ~]# pmap -x 18234 18234: nginx: worker process Address Kbytes RSS Dirty Mode Mapping 0000559bc4f00000 4 4 0 r---- nginx 0000559bc4f01000 796 796 0 r-x-- nginx 0000559bc4fc8000 224 144 0 r---- nginx 0000559bc5000000 20 20 20 rw--- nginx 0000559bc5005000 52 44 44 rw--- [ anon ] 0000559bc6d93000 1536 1408 1408 rw--- [ heap ] 00007fa1b8000000 132 132 132 rw--- [ anon ] 00007fb2c8000000 5164 4820 2340 rw--- libcrypto.so.3.0.7 00007ffe87b4a000 132 100 100 rw--- [ stack ] ---------------- ------- ------- ------- total kB 106700 18732 16988

-x出力の各列の意味:
Kbytes: 仮想メモリサイズ(予約済み)
RSS(Resident Set Size): 実際にRAMに乗っているサイズ。OOMキラーはこの値を参考にする
Dirty: ディスクへ書き戻しがまだの変更済みページ量

[heap]のRSSが時間とともに増え続けるようであれば、メモリリークの可能性があります。

3. より詳細な情報を表示する(-X・-XX オプション)

-Xはスワップ使用量・Pss(Proportional Set Size)など追加列を、-XXはカーネルが/proc/PID/smapsで公開するすべての情報を表示します。通常の調査では-xで十分ですが、詳細分析が必要な場合に使います。

# 拡張情報(Pss・Referenced・Anonymous・Swapなど) pmap -X 18234 # カーネルが公開する全情報(/proc/PID/smapsの内容に相当) pmap -XX 18234

実務でよく使うパターン

1. 複数プロセスを一括調査する

同名の複数ワーカープロセスを一括調査したい場合はpgrepと組み合わせます。

# nginx の全ワーカープロセスのRSS合計行だけ抽出する for pid in $(pgrep -x nginx); do echo -n "PID=$pid " pmap -x $pid | tail -1 done

検証サーバー(svr01)での実行例:

[root@svr01 ~]# for pid in $(pgrep -x nginx); do echo -n "PID=$pid "; pmap -x $pid | tail -1; done PID=18233 total kB 97400 16980 15400 PID=18234 total kB 106700 18732 16988 PID=18235 total kB 106700 18600 16820

3つのワーカープロセスのRSS合計がそれぞれ16~18MBほどであることが一目で分かります。

2. 出力をファイルに保存して差分を取る

メモリリークの調査では、時間を置いて2回測定し差分を比較するのが基本です。

# 1回目の記録(アプリ起動後など) pmap -x $(pgrep -f myapp) > /tmp/pmap_before.txt # 数時間後(高負荷後など)に2回目の記録 pmap -x $(pgrep -f myapp) > /tmp/pmap_after.txt # 差分を確認する diff /tmp/pmap_before.txt /tmp/pmap_after.txt

3. ヒープと匿名マッピングだけを抽出して傾向を掴む

grepを組み合わせることで、関心のある領域だけを素早く抽出できます。

# heap と anon の行だけを表示(全体から信号を絞り込む) pmap -x 18234 | grep -E 'heap|anon' # RSS列の合計を計算する(awkを使う) pmap -x 18234 | awk '/^[0-9a-f]/{rss+=$3} END{print "RSS合計:", rss, "KB"}'

「メモリが増え続けている」をpmapで追う実践例

Javaアプリケーションやデーモンが「起動直後は問題ないが数時間後にOOMになる」というケースを例に考えます。

# アプリ起動直後に記録(タイムスタンプ付きファイル名) [root@svr01 ~]# pmap -x $(pgrep -f myapp.jar) > /tmp/pmap_$(date +%H%M).txt # 3時間後に再度記録 [root@svr01 ~]# pmap -x $(pgrep -f myapp.jar) > /tmp/pmap_$(date +%H%M).txt # heap と anon の変化を比較 [root@svr01 ~]# grep -E 'heap|anon|total' /tmp/pmap_1000.txt | head -5 0000..0000 524288 401520 401520 rw--- [ heap ] total kB 892416 421380 418960 [root@svr01 ~]# grep -E 'heap|anon|total' /tmp/pmap_1300.txt | head -5 0000..0000 1048576 998400 998400 rw--- [ heap ] total kB 1572864 1019800 1017000

3時間でヒープのRSSが 401MB → 998MB に約2.5倍に増えています。これはメモリリークの有力な証拠です。このような場合の次のステップとしては、アプリケーション側のメモリ管理の調査(JavaならGCログの確認・ヒープダンプの取得)を行います。pmapは「どのプロセスのどの領域が膨らんでいるか」を素早く絞り込む道具として使います。

OOMキラーの発動を防ぐためのpmap活用

OOMキラーはシステムの空きメモリが枯渇した際にプロセスを強制終了します。pmap -xで各プロセスのRSS合計を定期的に記録しておくと、OOM発動前にメモリ消費の異常な増加を検知できます。

# cron で5分ごとにRSS上位5プロセスを記録するスクリプト例 # /etc/cron.d/pmap-monitor に配置する場合 */5 * * * * root for pid in $(ps -eo pid --sort=-%mem | head -6 | tail -5); do echo "$(date) PID=$pid $(pmap -x $pid 2>/dev/null | tail -1)"; done >> /var/log/pmap-monitor.log

定期記録を参照することで「OOM発動の1時間前から特定プロセスのRSSが急増していた」という原因の特定が後から行えます。なお、本番サーバーで定期的に全プロセスをpmap -xする場合は、/procへの読み取りアクセスが発生するため、数十秒に1回などの高頻度実行は注意が必要です。5分に1回程度が実運用での目安です。dmidecodeでハードウェア情報を取得して物理メモリの実装容量を把握しておくと、RSS合計との対比がしやすくなります。

トラブルシュート(pmapのよくあるエラー対処)

1. 「Operation not permitted」が出る

pmap: 18234: Operation not permitted

他のユーザーが所有するプロセスのメモリマップを確認しようとした場合に出ます。sudo pmap PIDで実行するか、root権限で実行してください。

2. 「No such process」が出る

指定したPIDのプロセスがすでに終了している場合に出ます。短命なプロセスを追う場合は、pgrep -f コマンド名で都度PIDを取得するか、スクリプトの$(pgrep -f ...)で動的にPIDを渡す方法が有効です。

3. pmapがインストールされていない

# RHEL/CentOS/Rocky Linux(procpsパッケージに含まれる) sudo dnf install procps-ng # Ubuntu/Debian(procpsパッケージ) sudo apt install procps # バージョン確認 pmap --version

RHELではprocps-ngに含まれており、最小インストールでも標準で入っているケースがほとんどです。

4. Dockerコンテナ内でpmapが使えない

コンテナ内からpmapを実行する場合、/procファイルシステムへのアクセスに制限があることがあります。ホスト側からpmap コンテナのPIDで確認する方法か、コンテナに--pid=host--cap-add=SYS_PTRACEを付けて起動する方法を検討してください。

本記事のまとめ

pmapコマンドの主なオプションと用途を整理します。

やりたいこと コマンド
プロセスの仮想メモリマップを確認 pmap PID
RSS・Dirtyの詳細を表示 pmap -x PID
スワップ・Pssも含めた拡張情報 pmap -X PID
smaps相当の全情報を表示 pmap -XX PID
同名プロセスを一括調査 pmap -x $(pgrep -x nginx)
ヒープ・匿名マッピングを抽出 pmap -x PID | grep -E 'heap|anon'
RSS合計を計算 pmap -x PID | awk '/^[0-9a-f]/{rss+=$3} END{print rss}'
ファイルに保存して差分を取る pmap -x PID > /tmp/pmap_before.txt
pmappstopでは見えないプロセス内部のメモリ構造を可視化する実務的なトラブルシューティングツールです。「メモリが増え続けているが原因が分からない」という場面で、まずpmap -x $(pgrep -f プロセス名)を実行して[heap]と[anon]のRSSを確認する習慣をつけると、問題の絞り込みが大幅に速くなります。

Linuxサーバーのメモリ管理をより体系的に学びたい場合は、Linux 基本コマンドの解説も合わせて参照してください。

「メモリが増え続けている」を自力で診断できる力は、Linuxサーバー管理の「型」から生まれます

pmapでプロセスのメモリマップを読めるようになると、OOM発動前に原因を特定できるようになります。こうした現場での問題解決力は、コマンドの使い方を覚えるだけでなく、Linuxのメモリ管理の仕組みを体系的に理解した上で身につくものです。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。

「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。