スワップ
このページでは GNU/Linux でのスワップとページングを紹介します。また、スワップパーティションとスワップファイルの作成と有効化について説明しています。
All about Linux swap space より:
- Linux は物理 RAM (random access memory) をページと呼ばれるメモリのかたまりに分割します。スワッピングとは、メモリを開放するために、ページがスワップ領域という名の事前設定領域にコピーされることを言います。物理メモリとスワップ領域の合計が利用できる仮想メモリのサイズになります。
スワップのサポートは Linux カーネルにより提供され、ユーザスペースのユーティリティは util-linux パッケージに存在します。
目次
スワップ領域
スワップ領域は普通ディスクパーティションとして作られますが、ファイルにすることもできます。Arch Linux のインストール中にユーザーはスワップ領域を作成することができ、必要であればインストール後でも作成できます。スワップ領域を作成する理由は2つあります: 仮想メモリを拡張して、搭載している物理メモリ(RAM)より多くするためと、suspend-to-disk(ハイバネート) をするためです。
スワップを使って仮想メモリを拡張することが利益になるかどうかは搭載している物理メモリの容量によります。必要なプログラムをすべて実行するのに必要な量の物理メモリを搭載していないのであれば、スワップを作成することはおそらく利益となるでしょう。これにより、out of memory(メモリ不足) を避けることができます。Out of memory とは、Linux カーネルの OOM killer という仕組みが自動的にプロセスを kill してメモリの空き領域を作ろうとしている状態のことを言います。仮想メモリの容量を必要な量まで増やすには、足りない分をスワップ領域として追加してください。
スワップの最大の欠点はパフォーマンスの低さです(#パフォーマンスチューニング セクションを見てください)。それゆえ、スワップを有効化するかどうかは個人の好みの問題となります。スワップを有効化するよりメモリが枯渇したときにプロセスが kill されるほうが良いという人もいますし、メモリが枯渇したときにシステムが低速化するがスワップを有効化したほうが良いという人もいます。
スワップの状態を確認するには、次を実行:
$ swapon --show
もしくは、以下を実行して物理メモリとスワップの使用状況を表示:
$ free -h
スワップパーティション
ほとんどの GNU/Linux の パーティショニングツール でスワップパーティションの作成ができます。スワップパーティションは、MBR ではタイプ 82
が、GPT では 0657FD6D-A4AB-43C4-84E5-0933C84B4F4F
が割り当てられています。
Linux のスワップ領域をセットアップする時には、mkswap
コマンドが使われます。例えば:
# mkswap /dev/sdxy
デバイスのページングを有効にするには:
# swapon /dev/sdxy
起動時にスワップパーティションを有効にするには、エントリを /etc/fstab
に追加します:
UUID=device_UUID none swap defaults 0 0
device_UUID
の部分はスワップ領域の UUID に変更してください。
ファイルの構文については fstab を見てください。
systemd による有効化
systemd は2つの異なる仕組みを使ってスワップパーティションを有効化します。どちらも実行可能ファイルは /usr/lib/systemd/system-generators
にあります。ジェネレータは起動時に実行され、マウントごとにネイティブの systemd ユニットを作成します。まず systemd-fstab-generator
が fstab を読み込んでユニットを生成します (スワップのユニットも)。次に systemd-gpt-auto-generator
が root ディスクを調査してユニットを生成します。後者は GPT ディスク上でのみ動作し、パーティションのタイプ GUID を見てスワップパーティションかどうかを識別します。さらなる情報については systemd#GPT パーティションの自動マウント を見てください。
スワップの無効化
特定のスワップ領域を無効にするには:
# swapoff /dev/sda2
もしくは -a
スイッチを使って全てのスワップ領域を無効化することもできます。
スワップが systemd によって管理されている場合、次の起動時に自動的に有効化されてしまいます。スワップ領域の自動有効化を無効にするには、systemctl --type swap
を実行して問題の .swap ユニットを確認してマスクしてください。
スワップファイル
パーティションを作るかわりに、オンザフライでサイズを変えたり簡単に削除できるものとしてスワップファイルが選択肢になりえます。特にディスク容量が貴重な場合 (例: 小容量の SSD) はこちらが理想的でしょう。
手動設定
スワップファイルの作成
root 権限で fallocate
を使ってあなたが決めたサイズでスワップファイルを作成します (M = メガバイト, G = ギガバイト) (dd
を使うこともできますが作成時間は長くなります)。例えば、512 MB のスワップファイルを作成するなら:
# fallocate -l 512M /swapfile
または:
# dd if=/dev/zero of=/swapfile bs=1M count=512
正しいパーミッションを設定します (スワップファイルを全てのユーザーが読めるようにすると深刻な脆弱性になります)
# chmod 600 /swapfile
正確なサイズのファイルを作成した後、ファイルをスワップにフォーマット:
# mkswap /swapfile
スワップファイルを有効に:
# swapon /swapfile
fstab を編集してスワップファイルのエントリを加えて下さい:
/etc/fstab
/swapfile none swap defaults 0 0
スワップファイルの削除
スワップファイルを削除するには、現在使っているスワップファイルを無効にしなければなりません。
root 権限で:
# swapoff -a
スワップファイルの削除:
# rm -f /swapfile
最後に /etc/fstab
からエントリを削除します。
自動設定
systemd-swap
systemd-swap は、zram スワップ、スワップファイル、およびスワップパーティションからハイブリッドスワップスペースを作成するためのスクリプトです。 systemd プロジェクトとは提携していません。
インストール は systemd-swap パッケージです。 /etc/systemd/swap.conf
の スワップファイルチャンク セクションで、コメントを解除して swapfc_enabled=1
を設定し、 systemd-swap
サービスを 起動・有効化 します。
詳細と設定については、 authors GitHub ページにアクセスしてください about-構成推奨構成。
USB デバイスとスワップ
Linux によるモジュール性のおかげで、私達は他のデバイスにわたる複数のスワップパーティションを使うことができます。あなたがひとつの完全なハードディスクを持っている場合、USB デバイスを一時パーティションとして使うことができます。ただしこのメソッドにはいくつか欠点も存在します:
- USB デバイスはハードディスクより低速です。
- フラッシュメモリには書き込み回数の上限があります。スワップパーティションとして使うと急速に書き込み可能回数を消費します。
- 他のデバイスをコンピュータに接続したときに、スワップが使われません。
USB デバイスをスワップに加えるには、まず USB フラッシュをスワップパーティションとしてパーティショニングします。Gparted などのグラフィカルツールや fdisk などのコンソールツールが使えます。パーティションテーブルを書き込む前にパーティションをスワップとしてラベル付けすることを忘れないで下さい。
fstab
を編集してスワップエントリのマウントオプションに以下を追加してください:
pri=0
USB が満杯の時はハードディスクのスワップのみを使うようになります。
上記の設定は SD カードなどでも使うことができます。
スワップの暗号化
dm-crypt/スワップの暗号化を見て下さい。
パフォーマンスチューニング
スワップ値を変えることでパフォーマンスを向上できるかもしれません。
Swappiness
swappiness sysctl パラメータはカーネルのスワップ領域の優先(もしくは回避)を表しています。Swappiness は 0 から 100 の間の値にすることができます。デフォルトの値は60です。このパラメータを低い値に設定すると RAM からのスワッピングが減り、多くのシステムでレスポンスが向上することが知られています。
現在の swappiness 値をチェックするには:
$ cat /proc/sys/vm/swappiness
swappiness 値を一時的にセットするには:
# sysctl vm.swappiness=10
swappiness 値を永続的にセットするには、sysctl 設定ファイルを編集します:
/etc/sysctl.d/99-sysctl.conf
vm.swappiness=10
テストしたり、なぜこれが働くのか知るには、この記事 を見て下さい。
この Q&A には swappiness について多くの情報が載っています。
他にもスワップのパフォーマンスに影響する sysctl パラメータとして vm.vfs_cache_pressure
が存在します。このパラメータはカーネルがページキャッシュやスワップに対して VFS キャッシュに使用されているメモリを回収する傾向をコントロールします。この値を増やすことで VFS キャッシュの回収がされやすくなります [2]。詳しい情報は、Linux カーネルドキュメント を見て下さい。
VFS cache pressure
スワップのパフォーマンスに影響を与えるもう1つの sysctl パラメーターは vm.vfs_cache_pressure
です。これは、ページキャッシュとスワップではなく、 VFS cache のキャッシュに使用されるメモリを再利用するカーネルの傾向を制御します。 この値を増やすと、VFS キャッシュが再利用される速度が上がります。 詳細については、Linuxカーネルのドキュメント を参照してください。
Priority
複数のスワップファイルやスワップパーティションを使っている場合、priority 値 (0 から 32767) をそれぞれのスワップ領域に割り当てることを考えて下さい。システムは優先度が低いスワップ領域を使う前に高い優先度が付けられたスワップ領域を使います。例えば、もしあなたが高速なディスク (/dev/sda
) と低速なディスク (/dev/sdb
) を持っている場合、高速なデバイス上のスワップ領域に高い優先度をあててください。priority は fstab で pri
パラメータを使って設定できます:
/dev/sda1 none swap defaults,pri=100 0 0 /dev/sdb2 none swap defaults,pri=10 0 0
もしくは swapon の -p
(もしくは --priority
) パラメータを使います:
# swapon -p 100 /dev/sda1
もし2つ以上の領域が同じ priority を持ち、それが一番高い priority の場合、その領域間ではラウンド・ロビン方式でページが配分されます。
zswap または zram の使用
Zswap は、スワップされたページに圧縮されたライトバックキャッシュを提供する Linux カーネル機能です。 これにより、パフォーマンスが向上し、IO 操作が減少します。
ZRAM は、ディスク上のスワップファイルの代わりに、メモリ内に仮想圧縮スワップファイルを作成します。
ストライピング
スワップの性能を上げるために RAID を使う必要はありません。/etc/fstab
ファイルでスワップの優先度が同じに設定されている場合、複数のデバイスにスワップをストライプ処理するのはカーネルだけで行うことができます。詳しくは The Software-RAID HOWTO を参照してください。