メモリ制約下における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 はホットデータの圧縮キャッシュとして、ディスクスワップはコールドデータの受け皿として——それが正しい方向だ。