ハードウェア基礎 #3 メモリ — RAM と階層構造、スワップが始まると起きること
#2 で、CPU はメモリを待つ時間を減らすためにキャッシュを置くと述べました。その待ち相手が今回の主題であるメモリです。メモリは普段は静かで、足りなくなる瞬間にシステム全体を崖の下へ落とします。その動作を理解すれば、「メモリ使用率が高いけれど大丈夫か」のような問いに測定で答えられるようになります。
ハードウェア基礎 シリーズでの今回の位置です。
- #1 コンピュータを動かす 4 つのリソース — CPU / メモリ / ストレージ / ネットワーク
- #2 CPU — コア / スレッド / クロック / キャッシュ、そして vCPU の正体
- #3 メモリ — RAM と階層構造、スワップが始まると起きること ← 今回
- #4 ストレージ ① デバイス — HDD / SSD / NVMe と IOPS / スループット / レイテンシ
- #5 ストレージ ② 構成と接続 — RAID と DAS / NAS / SAN
- #6 ネットワーク — 帯域幅とレイテンシ、NIC からデータセンターまで
- #7 仮想化とコンテナ — 物理サーバー 1 台が複数台になる仕組み
- #8 クラウド — 所有から賃借へ、オンプレミスから IaaS / PaaS / SaaS まで
- #9 クラウドインスタンスのスペックの読み方 — ワークロードに合わせて選ぶ
RAM とは何か #
RAM (Random Access Memory) は CPU がいま使うデータを置く作業空間です。プログラムを実行すると、そのコードとデータがストレージから RAM へ上がり、CPU は RAM に上がったものを読み書きします。
RAM には 2 つの重要な性質があります。
- 揮発性 — 電源が切れると中身が消えます。だから永続保管はストレージが担います。
- ランダムアクセス — どの位置でもほぼ同じ速度で読みます。順番に辿らないと速くない一部のストレージと違う点です。
核心は単純です。RAM は速いものの限られていて、電源が切れると中身が消える一時的な作業空間です。
メモリ階層 #
コンピュータの保存空間は 1 つではなく複数の層です。上に行くほど速く小さく高価で、下に行くほど遅く大きく安いです。
| 層 | おおよそのアクセス時間 | サイズ | 揮発性 |
|---|---|---|---|
| レジスタ | 1ns 未満 | 数百バイト | 揮発性 |
| L1 キャッシュ | 約 1ns | 数十 KB | 揮発性 |
| L2 / L3 キャッシュ | 数 ns ~ 数十 ns | 数 MB | 揮発性 |
| RAM | 約 100ns | 数 GB ~ 数百 GB | 揮発性 |
| SSD / NVMe | 数十 ~ 数百 μs | 数百 GB ~ 数 TB | 不揮発性 |
| HDD | 数 ms | 数 TB | 不揮発性 |
単位が 1 行下りるたびに大きく跳ねる点に注目します。RAM は約 100ns、SSD はそれより数百倍、HDD は数万倍遅いです。
RAM アクセス 100ns → 1 秒
SSD アクセス 100μs → 約 17 分
HDD アクセス 10ms → 約 28 時間この差が次の節の核心です。データが RAM にあるときと、ディスクまで下りなければならないときの違いがそれほど大きいのです。
容量・帯域幅・レイテンシは別の軸 #
メモリを語るとき 3 つがよく一緒くたにされます。区別しておくとスペック表が違って読めます。
| 軸 | 意味 | 足りないと |
|---|---|---|
| 容量 | 一度に置ける量 (GiB) | スワップが始まる |
| 帯域幅 | 1 秒に運べる量 (GB/s) | 大量処理で滞る |
| レイテンシ | 1 回のアクセスにかかる時間 (ns) | 頻繁なランダムアクセスで遅くなる |
運用でもっともよくぶつかるのは 容量 です。容量が足りなくなる瞬間、システムは遅いディスクを使い始め、そのとき性能が崩れます。
メモリが足りないと — スワップ #
メモリがいっぱいになると、OS はいま使っていないデータをディスクの 1 領域へ移して RAM に空きを作ります。この領域が スワップ (swap) で、移す動作が スワッピング です。Linux のスワップ設定は RHEL 基礎 #6 で実際のコマンドを使って扱いました。
スワップはメモリ不足でプロセスが死ぬのを防ぐ安全装置です。ただし代償が大きいです。先ほどの表を思い出すと、RAM は約 100ns、ディスクはそれより数百から数万倍遅いです。よく使うデータがスワップへ押し出されると、CPU は毎回ディスクを待つことになります。
正常: CPU → RAM (100ns) 応答が速い
不足: CPU → スワップ (ディスク, 数 ms) 応答が数千倍遅くなる
深刻: 読むそばからまた押し出される (スラッシング) システムがほぼ止まったように見えるデータをディスクへ下ろしてすぐまた必要になって上げ、また別のデータを下ろす、ということが繰り返される状態を スラッシング (thrashing) と言います。このとき CPU は計算よりデータを移すことに時間を使い、システムは止まったように遅くなります。「急にサーバーが応答しなくなった」のよくある原因です。
OOM Killer — Linux の最終手段 #
スワップまでいっぱいになり、メモリをこれ以上渡す先がなければ、Linux は OOM Killer (Out Of Memory Killer) を作動させます。メモリを多く使うプロセスを選んで強制終了し、システム全体が止まるのを防ぐ装置です。
運用でデータベースやアプリケーションが「原因なく死んだ」なら OOM Killer を疑います。ログに Out of memory: Killed process のような記録が残ります。解決はメモリを増やすか、プロセスのメモリ使用を減らすか、コンテナならメモリ上限を調整する方向です。
ページキャッシュ — 余ったメモリは遊んでいるのではない #
Linux で free コマンドを見ると、空きメモリが少なく見えて驚く場合が多いです。ほとんどは正常です。Linux は 余った RAM をディスクキャッシュ (ページキャッシュ) として活用 するからです。
一度読んだファイルを RAM にキャッシュしておけば、次に同じファイルをディスクまで行かずに RAM から即座に取れます。このキャッシュはアプリケーションがメモリを必要とすれば即座に返されます。
total used free buff/cache available
Mem: 16Gi 6Gi 0.5Gi 9.5Gi 9Gi
└─ キャッシュ └─ 実際に使える量見るべき値は free ではなく available です。buff/cache は必要なら回収されるので、available が十分ならメモリは足りています。free が 0 に近くても驚く必要はありません。
よく出会う落とし穴 #
「メモリ使用率 90% だけど増設すべきか」 #
数字だけではわかりません。その 90% にページキャッシュが含まれていれば正常です。available が十分か、スワップが実際に起きているかを見れば判断がつきます。
「スワップを入れておけば安全」 #
スワップは死ぬのを防ぐだけで、性能を守ってはくれません。スワップが本格的に使われ始めた時点で、すでに応答は崩れています。応答遅延のアラームとスワップ使用量を一緒に見る必要があります。
「メモリを増やせば速くなる」 #
#1 で押さえた誤解です。足りないときに増やせば崖を避けられますが、十分な状態でさらに増やしても速くはなりません。
「コンテナはホストのメモリを全部使える」 #
上限を掛けなければ、1 つのコンテナがホストのメモリを飲み込んで他のコンテナまで脅かします。運用ではメモリ上限を明示するのが安全です。コンテナのリソース隔離は #7 で扱います。
まとめ #
今回つかんだ絵です。
- RAM は CPU の作業空間です。速いものの揮発性で限られています。
- 保存空間は レジスタ → キャッシュ → RAM → SSD → HDD の階層で、1 層下りるたびに速度差が大きく開きます。
- メモリは 容量・帯域幅・レイテンシ が別々の軸です。運用でもっともよくぶつかるのは容量です。
- 容量が足りないと スワップ が始まり、ひどくなると スラッシング でシステムが止まったように遅くなります。
- 渡すメモリがなくなると OOM Killer がプロセスを強制終了します。
- Linux は余った RAM を ページキャッシュ として使います。
freeではなくavailableを見ます。
次回 — ストレージ #
メモリが足りないときにシステムが落ちる先がディスクでした。そのディスクが次の 2 つの記事の主題です。#4 ストレージ ① デバイス — HDD / SSD / NVMe と IOPS / スループット / レイテンシ では、ディスク 1 枚の種類と性能指標を整理します。HDD、SSD、NVMe が何で、どう違うのか、そして容量とよく混同される IOPS・スループット・レイテンシを切り分けます。