🧠
詳解 システム・パフォーマンス - 第7章:メモリ分析
Linuxメモリ管理の仕組み・OOM・スワップ・ページキャッシュ・メモリリーク検出まで。free/vmstat/pmap/valgrind/memleak の実践的な使い方。
Linux のメモリ管理の基本
重要な概念
| 概念 | 説明 |
|---|---|
| ページキャッシュ | ディスクデータを RAM にキャッシュ。フリーメモリが余れば使う |
| スワップ | RAM 不足時にディスクへページを追い出す。激遅になる |
| OOM Killer | メモリが完全に枯渇したらカーネルがプロセスを強制終了 |
| VSZ(仮想メモリ) | プロセスが要求した仮想アドレス空間の合計(実際には使っていない部分も含む) |
| RSS(常駐メモリ) | 実際に物理メモリに載っているページ |
| PSS | 共有ライブラリを均等割りした実質的なメモリ使用量 |
メモリの分類
物理メモリ(RAM)
├── カーネルメモリ(カーネル自身が使用)
└── ユーザーメモリ
├── アプリケーション(ヒープ・スタック・mmap)
└── ページキャッシュ(ファイルキャッシュ・バッファ)
↑ フリーメモリが余れば自動的に使われ、必要なら解放される
基本確認コマンド
free コマンドの正しい読み方
free -h
# total used free shared buff/cache available
# Mem: 16Gi 4.0Gi 2.0Gi 500Mi 10Gi 11Gi
# Swap: 2Gi 0 2Gi
# ポイント:
# - "free" が少なくても問題ない(キャッシュとして使われている)
# - "available" が実際に使えるメモリ(キャッシュを解放すれば使える分を含む)
# - available < total の 10% → 警戒ライン
# - Swap used > 0 → メモリプレッシャーが発生している
スワッピングの確認
# スワッピングが起きているか(si=スワップイン、so=スワップアウト)
vmstat 1 5
# si/so > 0 → スワッピング発生。アプリが激遅になっているはず
# スワップ使用量の推移を追う
sar -S 1 10
# kbswpused が増加傾向 → どんどんスワップを使い始めている
# スワップを最も使っているプロセス
for pid in /proc/[0-9]*/status; do
awk '/VmSwap/{print FILENAME": "$2" "$3}' $pid
done 2>/dev/null | sort -t: -k2 -rn | head -10
メモリ詳細
# カーネルのメモリ詳細(元データ)
cat /proc/meminfo
# MemTotal, MemFree, MemAvailable
# Buffers: ブロックデバイスのバッファ
# Cached: ページキャッシュ
# SwapCached: スワップに追い出してキャッシュにも残っているページ
# AnonPages: 匿名マッピング(ヒープ等)
# Shmem: 共有メモリ
# ページングの詳細
sar -B 1 5
# pgpgin/s: ディスクからページを読み込んだ回数(スワップイン含む)
# pgpgout/s: ディスクへページを書き出した回数
# majflt/s: メジャーページフォルト(ディスクI/Oが必要) → 高いとメモリ不足
# minflt/s: マイナーページフォルト(すでにキャッシュにある)
プロセス別のメモリ使用量
# メモリ使用量でソート(上位プロセス)
ps aux | sort -k4 -rn | head -10
# RSS 列(KB)が実際の物理メモリ使用量
# より詳細な情報
ps -eo pid,ppid,user,%mem,vsz,rss,comm --sort=-%mem | head -20
# プロセスのメモリセグメント詳細
pmap -x <PID>
# Address Kbytes RSS Dirty Mode Mapping
# 00400000 100 100 0 r-x-- myapp ← text(コード)
# 00800000 10 10 10 rw--- myapp ← data
# 019b0000 1024 1024 1024 rw--- ← heap(growsup)
# 7f1234... 2048 1024 0 r-x-- libc.so ← 共有ライブラリ
# heap の大きさを確認(メモリリークの兆候)
pmap -x <PID> | grep "\[heap\]"
メモリリーク検出
症状
# プロセスの RSS が時間とともに増え続けていないか確認
watch -n 5 'ps -p <PID> -o pid,rss,vsz,comm'
# RSS が増加し続け、かつプロセスを再起動すると正常に戻る → メモリリークの可能性
memleak(BCC tool):本番向け
# 指定プロセスのメモリ割り当てを追跡(60秒後にリークを報告)
sudo memleak -p <PID> -a 10
# -a 10: 上位10スタックを表示
# 出力例:
# [0x7f...] malloc+0x...
# [0x400...] cache_add+0x... ← キャッシュに追加しているが削除していない
# Total bytes: 52428800 (50 MB)
Valgrind:開発環境向け
# メモリリーク検出(本番では使わない ― 20〜30倍遅くなる)
valgrind --leak-check=full --show-leak-kinds=all ./myapp
# 出力例:
# LEAK SUMMARY:
# definitely lost: 1,024 bytes in 10 blocks ← 確実なリーク
# indirectly lost: 512 bytes in 5 blocks
# possibly lost: 256 bytes in 2 blocks
# still reachable: 4,096 bytes in 1 blocks ← 到達可能(許容範囲)
OOM(Out of Memory)の対処
OOM の検出
# OOM Killer が発動したか確認
dmesg | grep -i "out of memory"
dmesg | grep -i "oom-killer"
# 出力例:
# kernel: Out of memory: Kill process 12345 (java) score 900 or sacrifice child.
# kernel: Killed process 12345 (java) total-vm:8388608kB, anon-rss:7340032kB
# systemd ジャーナルから確認
journalctl -k | grep -i "out of memory"
OOM が起きた場合の調査
# 1. どのプロセスが殺されたか
dmesg | grep "Killed process"
# 2. 当時のメモリ使用量を確認
dmesg | grep -A 20 "out of memory"
# OOM時のプロセスごとのメモリ使用量が出力される
# 3. スコアの確認(高いほど OOM killer に狙われやすい)
cat /proc/<PID>/oom_score
cat /proc/<PID>/oom_score_adj # -1000(保護)〜1000(積極的に殺す)
# 4. OOM を起こしたプロセスの保護(緊急措置)
echo -1000 > /proc/<PID>/oom_score_adj # このプロセスを保護
チューニング
スワップ設定
# スワップの積極度を下げる(メモリに余裕があるうちはスワップしない)
sysctl vm.swappiness=10 # デフォルト60 → 10に下げる(0は非推奨)
# 永続化:
echo "vm.swappiness=10" >> /etc/sysctl.conf
# スワップを無効化(メモリが十分な環境)
swapoff -a
大きなページ(HugePage)
# HugePage の使用状況確認(DB等で効果的)
cat /proc/meminfo | grep -i huge
# HugePages_Total: 1024
# HugePages_Free: 0 ← 全部使用中
# Transparent HugePage の状態
cat /sys/kernel/mm/transparent_hugepage/enabled
# [always] madvise never
メモリ問題のチェックリスト
□ free -h で available を確認(10%以下で警戒)
□ vmstat 1 で si/so 列を確認(スワッピング発生?)
□ dmesg で OOM Killer の発動を確認
□ ps で RSS が増加し続けているプロセスがないか確認
□ pmap で heap のサイズを確認
□ sar -B でメジャーページフォルト数を確認
□ vm.swappiness の設定値を確認(高すぎないか) - 1. 📊詳解 システム・パフォーマンス - 概要・読み方ガイド
- 2. 🔍詳解 システム・パフォーマンス - 第16章:ケーススタディ
- 3. 🧭詳解 システム・パフォーマンス - 第2章:メソドロジ
- 4. 🐧詳解 システム・パフォーマンス - 第3章:オペレーティングシステム
- 5. 🔭詳解 システム・パフォーマンス - 第4章:可観測性ツール
- 6. ⚙️詳解 システム・パフォーマンス - 第5章:アプリケーション
- 7. 💻詳解 システム・パフォーマンス - 第6章:CPU分析
- 8. 🧠詳解 システム・パフォーマンス - 第7章:メモリ分析
- 9. 📁詳解 システム・パフォーマンス - 第8章:ファイルシステム分析
- 10. 💾詳解 システム・パフォーマンス - 第9章:ディスク分析
- 11. 🌐詳解 システム・パフォーマンス - 第10章:ネットワーク分析
- 12. ☁️詳解 システム・パフォーマンス - 第11章:クラウドコンピューティング
- 13. 📏詳解 システム・パフォーマンス - 第12章:ベンチマーキング
- 14. 🔥詳解 システム・パフォーマンス - 第13章:perf
- 15. 🔬詳解 システム・パフォーマンス - 第14章:Ftrace
- 16. ⚡詳解 システム・パフォーマンス - 第15章:BPF/eBPF
出典: 詳解 システム・パフォーマンス 第2版 Brendan Gregg著