スワッピングは、物理メモリが足りなくなったときにOSがメモリの内容を補助記憶へ退避させ、空きを作り出す仕組みです。現場で問題になるのは「スワップが使われている状態が異常なのか、正常な範囲なのか」の切り分けにあります。この記事では、スワッピングとページングの定義の差、free・swapon・vmstatでの状態確認、vm.swappinessの0から200という範囲の意味、/proc/pressure/memoryでのスラッシング判定、cgroup v2とkubeletでの扱い、zramとzswapの位置づけを、実行できるコマンドと公式ドキュメントの記述に沿って追いました。スワップを残す条件と無効にすべき条件も判断できる形で示します。
まとめ:スワップを残す条件とスラッシング判定を先に示す優先順位
スワッピングは、主記憶の空きが不足したときに使われていないメモリ内容を補助記憶へ書き出し(スワップアウト)、必要になったら読み戻す(スワップイン)動作です。古典的な定義はプロセス全体を退避させる方式を指しますが、現行のLinuxやWindowsが行うのはページ単位の退避で、現場で「スワップしている」と言うときの実体はページアウトです。
スワップ領域が確保されていること自体は障害ではありません。問題は、退避と読み戻しが継続的に往復してCPUがI/O待ちで止まる状態、つまりスラッシングです。判定の順序は固定できます。まずvmstatのsi・so列で入出力が起きているかを見て、次に/proc/pressure/memoryのfull行で全タスクが同時に停止している割合を見る。両方が上がっていればスラッシングで、swappinessの調整ではなく物理メモリの増設か常駐プロセスの削減が答えです。使用量が数百MBあってもsi・soが0のままなら対処は要りません。
スワッピングの定義とスワップイン・スワップアウトが発生する条件の整理
定義を先に固めます。ここが曖昧だと、計測値の読み方も定まりません。
主記憶の空きが不足したときにプロセス全体を退避させるスワップアウトの動き
スワッピングの原義は、実行中のプロセスが使っているメモリ領域を丸ごと補助記憶へ書き出し、主記憶に空きを作る方式です。基本情報技術者試験で「実記憶管理におけるスワッピング方式」として説明されるのがこの定義で、優先度の低いプロセスを退避対象に選び、実行順が回ってきたら読み戻す前提で設計されていました。プロセス全体が単位である以上、退避も復帰も一度に大量のI/Oが走ります。数百MBのプロセスを丸ごと書き出せば、その間そのプロセスは動けません。単位の粗さが、この方式の限界でした。
現行Linuxでの退避がページ単位で起きる仕組みと用語のずれ方
現在のLinuxが行うのはプロセス単位ではなくページ単位の退避です。カーネルは各ページのアクセス状況を追跡し、一定期間触られていない匿名ページ(ファイルに対応しないヒープやスタックの領域)をスワップ領域へ書き出します。仮想メモリを物理ページへ割り付ける処理そのものもカーネルの担当で、この層の役割分担はカーネルがOSの中核として担う機能を整理した記事で確認できます。
それでも「スワップ」という語は残りました。退避先の領域はswapパーティション、swapファイルと呼ばれ、コマンドもswaponのままです。用語は古典的なスワッピング、実装はページング。読み替えの規則はひとつです。設定ファイルやコマンド名の「swap」は退避先の領域を指し、性能の話の「スワップしている」はページ単位の退避が起きている状態を指す、と分けてください。
スワッピングとページングの違いを退避単位と発生契機で切り分ける整理
試験でも実務でも問われるのがこの差です。2軸で並べると混乱しません。
退避の単位と発生の契機で並べたスワッピングとページングの対比表
両者はメモリ不足への対処という目的を共有し、退避の粒度と契機が異なります。
| 観点 | スワッピング(古典的定義) | ページング |
|---|---|---|
| 退避の単位 | プロセス全体のメモリ領域 | 固定長のページ(x86_64は4KiBが基本) |
| 発生の契機 | 主記憶の空き不足とプロセスの優先度 | ページフォールト、およびカーネルによる回収 |
| 現行OSでの扱い | 用語と領域名として残存 | 実際の退避機構 |
| 関連する主な指標 | swpd(退避済み総量) | si・so(入出力の実測)、pgfault |
押さえるべきは最下段です。確保量や退避済み総量を示すswpdは、いま性能に影響しているかを教えてくれません。判断材料はsi・soのほう。障害報告でも用語だけで済ませず「スワップ領域への退避が発生(vmstatのsoが継続的に非ゼロ)」と指標名まで添えてください。ページキャッシュの解放とスワップアウトを混同した報告も多く、両者の区別はディスクキャッシュとメモリキャッシュの違いを整理した記事が参考になります。
free・swapon・vmstatでスワップ発生をコマンドで確認する手順
状態を見ずに設定を触るのが最も多い失敗です。確認は3コマンドで足ります。
free -hとswapon –showで確保量と使用量を突き合わせる確認手順
まず領域が確保されているか、どれだけ使われているかを見ます。
free -h
swapon --show
cat /proc/swaps
free -hのSwap行のtotalが0なら、そのホストにスワップ領域はありません。swapon --showは領域ごとにNAME・TYPE・SIZE・USED・PRIOを返します。PRIO列はswapon(8)のマニュアルが定めるとおり0から32767の範囲で、明示しない場合はカーネルが負の値を割り当てる仕様。速いデバイスを先に使わせたいときは--priorityで明示してください。
スワップファイルの新規作成には制約があります。同じマニュアルは、カーネルがファイルへ直接書き込むため穴(hole)のあるファイルは拒否されると明記し、cpやtruncateではなくddと/dev/zeroを使う方法を最も互換性が高いとしています。btrfsでの対応はLinux 5.0以降のnocow属性ファイルに限られる点も押さえてください。
sudo dd if=/dev/zero of=/swapfile bs=1M count=4096 status=progress
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon --priority 10 /swapfile
swapon --show
領域のサイズ設計と/etc/fstabへの恒久登録までを含めた運用手順は、Linuxのスワップ領域の確認・推奨サイズ・vm.swappinessの設定をまとめた記事に分けてあります。
vmstatのsi・soが0のままかで実I/Oの発生を切り分ける判定基準
使用量の値だけでは、いま退避が起きているかは分かりません。時系列で見ます。
vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
読む列は3つです。swpdは退避済みの累計量、siは1秒あたりのスワップイン量、soはスワップアウト量。swpdが数GBに達していてもsiとsoが0で並ぶなら、過去に退避したページが放置されているだけで現在の性能には効いていません。逆にswpdが小さくてもsiとsoが毎秒動き続けるホストは、少量のメモリを奪い合って往復している状態です。判定は閾値より継続時間で見ると外しません。5秒間隔で30回取り、si・soが非ゼロだった回数を数える。1、2回なら一時的な負荷、常時非ゼロならメモリ設計の見直し対象です。
vm.swappinessの0〜200という範囲と既定値60が示すIOコスト比
最初に触られる調整パラメータがswappinessです。意味を取り違えたまま0を書き込む例が多いため、一次情報から確認します。
0から200の範囲と既定値60というカーネル公式ドキュメントの記述
Linuxカーネル公式のvm sysctlドキュメントは、swappinessを「スワップとファイルシステムのページングの、おおよその相対的なI/Oコストを定義する制御であり、0から200の値をとる」と定義し、既定値を60としています。「スワップの積極性を示す0から100のパーセンテージ」ではない点が要注意。上限は200で、匿名ページの回収とファイルバックのページの回収のどちらを選ぶかという天秤の傾きを表します。同ドキュメントは、zramやzswapのようにメモリ上で完結するスワップでは100超も検討対象になると記しています。100がファイルキャッシュ側と対等、それより上はスワップ側を優先する設定です。
swappiness 0でも退避が完全には止まらない挙動と恒久設定の書き方
0を設定しても、スワップアウトが禁止されるわけではありません。同じドキュメントは「0のとき、カーネルは空きページとファイルバックのページの合計がゾーンのhighウォーターマークを下回るまでスワップを開始しない」と説明しています。逼迫すれば0でも退避する、ということです。「swappiness=0はスワップを使わない設定」という説明は、この記述と一致しません。完全に使わせないならswapoffで領域そのものを外してください。
cat /proc/sys/vm/swappiness
sudo sysctl -w vm.swappiness=10
echo 'vm.swappiness = 10' | sudo tee /etc/sysctl.d/99-swappiness.conf
sysctl -wは再起動で失われるため、恒久化するなら/etc/sysctl.d/配下に置きます。もう1つの調整対象が同ドキュメントのwatermark_scale_factorで、既定値10はウォーターマーク間の距離がノードの利用可能メモリの0.1%を意味し、上限は3000(30%)。回収が間に合わず割り当てが待たされるホストでは、swappinessよりこちらが効きます。
/proc/pressure/memoryとsi・soでスラッシングを判定する切り分け
スワップの発生とスラッシングは別の事象です。区別する指標がカーネルにあります。
/proc/pressure/memoryのfull行が示す全タスク停止時間の割合
PSI(Pressure Stall Information)は、リソース待ちで処理が止まっていた時間の割合を報告します。カーネル公式のPSIドキュメントによれば、someは「少なくとも一部のタスクが当該リソースで停止していた時間の割合」、fullは「アイドル以外の全タスクが同時に停止していた時間の割合」。avg10・avg60・avg300は10秒・60秒・300秒のウィンドウでの割合で、totalは累積停止時間をマイクロ秒で表します。
cat /proc/pressure/memory
some avg10=0.00 avg60=0.00 avg300=0.00 total=0
full avg10=0.00 avg60=0.00 avg300=0.00 total=0
同ドキュメントは、fullの上昇がワークロードのスラッシング状態を示唆し、性能に重大な影響を与えると明記しています。CPUサイクルが完全に無駄になる区間だからです。someが数%動く程度なら通常の範囲、fullのavg10が継続して二桁になるホストは設定調整の段階を過ぎています。
si・soとPSIとOOM Killerの3点を突き合わせる切り分けの順序
調査の順序を固定すると切り分けが早く済みます。
vmstat 1のsi・soで、退避と読み戻しが継続しているかを見る/proc/pressure/memoryのfull avg10で、全タスクが止まっている割合を見るdmesgやjournalctl -kでOut of memoryの記録とkilled processの行を探す
1と2が同時に上がっていればスラッシングで、対処は物理メモリの増設か常駐プロセスの整理です。1だけが動いて2が静かなら、退避は起きていても待ちは発生しておらず緊急性はありません。1と2が静かで3のOOM Killerだけが動くホストは、スワップ領域が無いか使い切っていて、粘る余地がないまま殺されています。この場合はswappinessより領域の確保が先。特定プロセスのメモリが単調増加しているなら退避量の調整では止まらないため、メモリリークの原因特定と対処の記事を参照してください。
コンテナのmemory.swap.maxとkubeletのNoSwap既定という制約
コンテナ環境では、ホスト側の設定と別にcgroupの制限が効きます。ホストで有効でも、コンテナが使えるとは限りません。
cgroup v2のmemory.swap.maxでコンテナ単位の上限を読む方法
cgroup v2の公式ドキュメントは、memory.swap.maxを「スワップ使用量のハードリミット」と定義し、上限に達するとそのcgroupの匿名メモリはスワップアウトされないこと、既定値がmax(上限なし)であることを示しています。memory.swap.highは「スワップ使用量のスロットル上限」で、超過すると以降の割り当てがスロットルされます。
cat /sys/fs/cgroup/system.slice/memory.swap.max
cat /sys/fs/cgroup/system.slice/memory.swap.events
調査で見る価値が高いのはmemory.swap.eventsです。同ドキュメントによれば、highはhigh閾値を超えた回数、maxはmax境界を超えそうになって割り当てに失敗した回数、failはシステム全体のスワップ枯渇またはmax上限で失敗した回数。failが増えているコンテナは、退避したくてもできずにOOMへ向かっている状態で、上限値の設計を見直す対象になります。
LimitedSwapでBurstableのみ許可されるスワップ量の算出式
Kubernetesでは扱いがさらに絞られます。公式のスワップメモリ管理ドキュメントが示すのは、Linuxノードで選べる挙動がNoSwap(既定)とLimitedSwapの2つであること、スワップ有効なノードでkubeletを起動するにはfailSwapOn: falseが要ること、コンテナランタイムがcgroup v2のmemory.swap.maxに対応している必要があること。NoSwapを選んでもワークロードが使わないだけで、systemdのサービスやkubelet自身といったKubernetes管理外のプロセスはスワップを使えます。
failSwapOn: false
memorySwap:
swapBehavior: LimitedSwap
どのPodが使えるかはKEP-2400のREADMEが定めています。許可されるのはBurstable QoSのPodのみ。Guaranteedは性能劣化を避けるため、BestEffortはノード逼迫時に最初に退去する対象であるため、いずれも除外されます。上限は、コンテナのメモリ要求をノードの物理メモリ総量で割った比率に、Podが使えるスワップ総量を掛けた値。requestsとlimitsを同値にしたコンテナは比率が0と定義され、スワップ上限も0になります。Guaranteedにすれば安全という設計判断が、そのままスワップを使えない設定になる点は把握しておいてください。
zramとzswapで圧縮に置き換える構成と採用が効く場面の条件
ディスクI/Oを伴う退避を減らす選択肢が、メモリ内圧縮です。似た名前ですが役割は違います。
zswapの圧縮キャッシュとzram採用が効く条件・見送る条件
カーネル公式のzswapドキュメントは、zswapを「スワップアウト対象のページを圧縮してRAM上のプールに保持する軽量な圧縮キャッシュ」と定義しています。既存のスワップデバイスを置き換えるのではなく、その前段に挟まる位置づけ。プールが上限に達すると、LRUの順にページがバッキングのスワップデバイスへ書き出されます。有効かどうかはCONFIG_ZSWAP_DEFAULT_ONというKconfigオプションに依存し、カーネルコマンドラインのzswap.enabled=0で既定を上書きできます。実行中に切り替えるならsysfs経由です。
cat /sys/module/zswap/parameters/enabled
echo 1 | sudo tee /sys/module/zswap/parameters/enabled
一方のzramは、圧縮ブロックデバイスをRAM上に作り、そこをswaponでスワップ領域にします。退避先がメモリ内に閉じるため、物理ディスクが遅い環境や書き込み寿命を消費したくない環境で効きます。見送る条件も明確です。CPUが既に飽和しているホストでは圧縮と伸長のコストが上乗せされ、状況が悪化する。既に圧縮済みのデータ(画像・動画・暗号化済みデータ)を大量に抱えるプロセスでも、費やしたCPUに見合う削減は得られません。前章のswappinessを100超にする検討が意味を持つのも、こうしたメモリ内スワップの構成に限られます。
スワップを残す条件と無効にする場面:受託開発の現場からの判断基準
「スワップは切るべきか」は設計レビューで繰り返し出ます。条件で切り分ければ案件ごとに迷いません。
メモリスパイクの吸収とOOM Killer回避のためにスワップを残す条件
スワップを残すのは、突発的なメモリ使用の山を吸収したい場合です。日次バッチが月末だけ通常の3倍を要求する、デプロイ時に旧プロセスと新プロセスが並走する、といった構成では、スワップが無いホストはその瞬間にOOM Killerを呼びます。強制終了して初めて気づく障害より、数十秒遅くても完走するほうが被害は小さい。
長期間触られない常駐プロセスを抱えるホストでも残す価値があります。監視エージェントやログ収集は、起動時に確保したメモリの大半をその後使いません。この種のページを退避させ、空いた物理メモリをページキャッシュに回すほうが全体のI/Oは減ります。swappinessを1桁に下げてスワップは残す構成が折衷案になります。
低レイテンシDBとKubernetesノードでスワップを無効にする判断
逆に、切るべき場面は3つです。第一に、応答時間の上限が契約で決まっているデータベースやキャッシュサーバー。退避されたページの読み戻しはミリ秒単位の遅延を生み、95パーセンタイル値を跳ね上げます。予測可能な失敗(OOMで落ちて再起動)のほうが、予測不能な遅延より運用しやすい領域です。第二に、Guaranteed QoSを前提に容量設計をしているKubernetesのワーカーノード。前述のとおりスワップを使えず、ノードの挙動が読みにくくなるだけです。第三に、メモリ使用量の上限が実測で確定し、物理メモリに余裕があるホスト。切り分け要因が増えるだけです。
判断を言い切ります。汎用の業務システムサーバーとバッチ処理ホストではスワップを残し、swappinessを10前後まで下げる。レイテンシ保証のあるDBとKubernetesノードでは無効にし、そのぶん物理メモリを積む。「とりあえず既定のまま」が最も損をする選択です。インフラ構築(AWS・Google Cloud・Azure)のサービスでは、メモリ設計とインスタンスサイズの決定を実測値から引き受けています。
よくある質問
スワッピングの調査と設定変更でよく聞かれる質問を、一次情報の記述に沿ってまとめます。
スワップ領域のサイズは物理メモリの何倍にすべきですか?
「物理メモリの2倍」は物理メモリが数百MB程度だった時代の名残で、現在のカーネル公式ドキュメントにこの倍率の規定はありません。ハイバネーション(休止状態)を使うなら物理メモリ以上が必要。使わないなら、スパイクを吸収できる数GB程度から始め、vmstatのsi・soの実測で増減させてください。
vm.swappinessを0にすればスワップは完全に無効になりますか?
なりません。カーネル公式のvm sysctlドキュメントは、0のときも空きページとファイルバックのページの合計がゾーンのhighウォーターマークを下回ればスワップを開始すると記しています。0は「スワップ禁止」ではなく「ファイルキャッシュ側の回収を優先する」設定です。使わせないならswapoff -aで領域を外し、/etc/fstabのswap行も削除してください。
スワップを使っているのに動作が遅くない場合、対処は必要ですか?
不要です。freeのSwap usedが数百MBあってもvmstatのsiとsoが0で並ぶなら、退避されたページが読み戻されないまま置かれているだけで、現在のI/Oには影響していません。対処が要るのは、si・soが継続的に非ゼロで、かつ/proc/pressure/memoryのfull行が上昇している場合だけです。
Kubernetesのノードでスワップを有効にするとPodはどう扱われますか?
kubeletの既定はNoSwapで、この状態のワークロードはスワップを使いません。LimitedSwapに切り替えても、KEP-2400の規定で使えるのはBurstable QoSのPodのみ。GuaranteedとBestEffortは除外されます。NoSwapのままでもkubelet自身などKubernetes管理外のプロセスは使える点が公式ドキュメントに明記されています。
zramとzswapはどちらを選べばよいですか?
役割が違うため、選ぶ基準も分かれます。zswapは既存のスワップデバイスの前段に置く圧縮キャッシュで、物理的なスワップ領域を持つ構成の改善向き。zramは圧縮ブロックデバイス自体をスワップ領域にするため、ディスクを持たない構成や書き込み寿命を抑えたい環境に向きます。どちらもCPUを消費するので、使用率が既に高いホストでは選びません。
関連記事
- Linuxのスワップ領域(swap)とは|確認・推奨サイズ・vm.swappinessの設定を実コマンドで解説:Linux単一環境でのサイズ設計とfstab登録までの運用手順を扱っています
- メモリリークとは?原因の特定方法と直し方を言語・環境別に解説:退避量の調整では止まらない、単調増加の原因側を特定する手順が分かります
- Javaヒープとは?メモリ構造・サイズ設定・OutOfMemoryErrorの対処:JVMのヒープ設定とホストの物理メモリ配分を突き合わせる際の前提になります
- Native Memory Tracking(NMT)とは?jcmdでJVMのネイティブメモリを調べる手順:ヒープ外の領域が退避対象になっているかを切り分けるときに使えます
- Elasticsearchのチューニング|メモリ配分とシャード設計・遅いクエリの特定手順:スワップを嫌うミドルウェアでのメモリ配分の具体例として参照できます