メモリ制約下におけるZRAMとZSWAPの挙動の違い
8GB の物理メモリを搭載したマシンで IDEA、Docker、Chromium を同時に動かす——メモリ逼迫は日常茶飯事だ。よくある対策は ZRAM ブロックデバイスを最も優先度の高いスワップ先に設定すること。この構成は確かに純粋なディスクスワップよりかなり速いが、数日間稼働させると、それでも深刻なレイテンシジッターが発生する:マウスがカクつき、ウィンドウ切り替えに数秒の遅延が生じる。
問題は ZRAM そのものではなく、回収ポリシーとストレージバックエンドのミスマッチにある。
ZRAM vs ZSWAP:アーキテクチャ上の根本的な違い
どちらもメモリ圧縮を行うが、その位置づけはまったく異なる。
ZRAM は圧縮ブロックデバイスである。 カーネル内に /dev/zramX ブロックデバイスとして登録され、ストレージバックエンドはメモリ上の圧縮ページである。データは swap_writepage() を通じて流入し、標準的なブロック I/O パスを経由する。ZRAM はコールドページとホットページの区別を持たない——単なる媒体であり、回収の意思決定には関与しない。プールが満杯になれば swap_info の優先度に従って次のスワップデバイスにフォールバックするだけで、ポリシーは一切存在しない。
ZSWAP は圧縮キャッシュ層である。 スワップサブシステム内部に組み込まれ、shrink_page_list() の回収パスの早い段階でページを直接インターセプトする。ZSWAP は圧縮ページのメタデータを保持し、カーネルの LRU と連携して動作する。ソフトリミット max_pool_percent を持ち、プールが満杯になると、無分別にオーバーフローさせるのではなく、最もコールドなページをバックエンドのディスクスワップにライトバックし、アクティブなデータのためにスペースを空ける。
このアーキテクチャ上の差異が、持続的な高負荷下で両者をまったく異なる結果へと導く。
LRU 逆転:高速メディアにゴミが溜まり、ホットデータは低速ディスクに取り残される
Linux のページ回収に期待される動作はシンプルだ:まず Inactive(コールド)ページを追い出し、Active(ホット)ページを保護する。
しかし、次の構成を見てほしい:
/dev/zram0:優先度 32767(最高)- ディスクスワップ:優先度 -1
システム起動フェーズでは大量の一度きりの初期化データが生成され、これらのコールドページは回収時に真っ先に優先度の最も高い ZRAM に入る。ZRAM が満杯になった後、コアワーキングセット(IDEA や Docker のホットページ)をスワップアウトする必要が生じても、ZRAM には空きがなく、これらのページは強制的にディスクスワップへリダイレクトされる。
コールドデータが高速な ZRAM を占有し、ホットデータが低速なディスクに取り残される——LRU の追い出し意図はスワップ優先度の設定によって完全に覆される。これが LRU 逆転 であり、カーネル MM メンテナ(Chris Down など)はこのような混在構成を明確に非推奨としている。
ライトバック戦略:受動的な拒否 vs 能動的なエージング
| 特性 | ZRAM | ZSWAP |
|---|---|---|
| トリガー機構 | 手動設定または新しいカーネルでのサポート | zswap_shrink() による自動発動 |
| ポリシー根拠 | プール枯渇に基づく(ポリシーなし) | LRU エージングに基づく |
| MM との統合度 | MM サブシステムから独立 | Reclaim パスに深く組み込み |
ZSWAP は最も長期間アクセスされていないページを動的にディスクへ押し出し、現在アクティブなページのためにプールスペースを解放できる。ZRAM は満杯になればサービスを拒否するしかない。
I/O パスのオーバーヘッド
ZRAM の書き込みパスにはブロック層の完全なオーバーヘッドが乗る:
メモリページ → BIO 割り当て → リクエストキュー → I/O スケジューリング → ZRAM ドライバ → 圧縮
ZSWAP はこれらをすべてバイパスする:
メモリページ → ZSWAP フック → 圧縮
もっとも、デスクトップのユースケースにおいて ZSWAP の実際の利点は、パスの短縮よりも 低速ディスク I/O の発生頻度の低減 にある——LRU を認識した追い出しにより、スワップアウトの大部分は圧縮キャッシュ層内に留まり、真にコールドなページだけがディスクに落ちる。
制約と境界
両者に共通する制限:
- HugeTLB ページ:非サポート。
- Tmpfs ページ:スワップパスを経由せず、管理対象外。
- Mlocked ページ:スワップアウト不可。
重要な違い:ZSWAP はバックエンドストアとしてディスクスワップを必須とする——本質的にキャッシュ層だからだ。ZRAM はディスクなしで独立して存在できる。
選び方
ディスクスワップのあるデスクトップ/サーバー環境では、ZSWAP をそのまま使う。root で実行:
swapoff /dev/zram0
echo 1 > /sys/module/zswap/parameters/enabled
echo zstd > /sys/module/zswap/parameters/compressor
echo 50 > /sys/module/zswap/parameters/max_pool_percent
いくつかの心得:
- ZRAM の正しいユースケースは、組み込み機器や Android のようなディスクレス環境であり、「ディスクがない状況でスワップを提供する」ことが設計目標である;
- ディスクのあるマシンで ZRAM とディスクスワップを混在させると、上述の LRU 逆転問題を引き起こすため、ZRAM は無効にすべきである;
- ZSWAP とディスクスワップの組み合わせは、現在のデスクトップ Linux において最も安定したメモリ逼迫対策であり、圧縮をキャッシュとして扱い、真にコールドなデータだけをディスクに落とす。
ZRAM は優れたストレージバックエンドだが、回収のインテリジェンスを持たない。ZSWAP は圧縮と追い出しポリシーを一体のものとして結びつけている。ディスクのある環境では、それぞれを本来の役割に徹しさせる——ZSWAP はホットデータの圧縮キャッシュとして、ディスクスワップはコールドデータの受け皿として——それが正しい方向だ。