実体メモリ(物理メモリ)の仕組みと管理 — OSとハードで深掘り

はじめに:実体メモリとは何か

「実体メモリ(物理メモリ)」は、システム内で実際に搭載されるRAM(Random Access Memory)を指します。CPUが直接アクセスする実際のアドレス空間であり、プログラムのコードやデータ、カーネルの構造体、ページキャッシュなどが配置されます。仮想メモリと対比して語られることが多く、OSとハードウェアの双方の仕組みを理解することで、パフォーマンスや信頼性の最適化に直結します。

実体メモリと仮想メモリの関係

現代の一般的なOSは仮想メモリ方式を採用しています。プロセスは仮想アドレスを使ってメモリを参照しますが、実際の読み書きはMMU(Memory Management Unit)により仮想アドレス→物理アドレス(実体アドレス)へ変換されます。この変換はページテーブルとTLB(Translation Lookaside Buffer)を用いて行われます。したがって、実体メモリは仮想アドレス空間を支える背後のリソースです。

ハードウェア側の要素

  • DRAMセル:実体メモリの大半はDRAMで構成されます。DRAMは行・列で整理され、セルのリフレッシュが必要です。

  • 物理アドレス(PA):メモリコントローラが扱う実際のアドレス。CPUは仮想アドレス(VA)を使い、MMUがPAへ変換します。

  • MMUとTLB:MMUはページテーブル参照を行い、TLBはその結果をキャッシュして高速化します。TLBミスが多いとパフォーマンスが低下します。

  • IOMMU:DMAを使うデバイス向けに、デバイスからの物理メモリアクセスを制御・翻訳します。セキュリティや仮想化で重要です。

OSによる実体メモリ管理

OSは実体メモリをページフレーム単位で管理します(通常4KiB, 大ページは2MiB/1GiBなど)。主な役割は割り当て・解放・フラグメンテーション管理・スワップ管理・キャッシングの制御です。代表的な管理機構を以下に示します。

  • ページフレーム管理:物理ページの使用状況をビットマップやポインタリストで追跡します。

  • アロケータ(例:Buddy Allocator、slab/SLUB):連続した物理ページを効率よく割り当てるための構造。カーネル内部の小さなオブジェクト管理にslab系が使われます。

  • ページキャッシュ:ディスクI/Oを低減するためにファイルデータを物理メモリにキャッシュします。大量の物理メモリはI/O性能向上に寄与しますが、キャッシュとプロセスメモリのバランス調整が必要です。

  • スワップ:物理メモリが不足した場合、ページをストレージ上のスワップ領域に退避させます。スワップはメモリ不足の回避手段ですが、ディスク遅延によりパフォーマンスが著しく落ちます。

重要な概念:フラグメンテーションと連続性

物理メモリでは、使用と解放を繰り返すうちに小さな空き領域が点在する「フラグメンテーション」が発生します。特にデバイスが連続した物理メモリを要求する(DMA、巨大ページの割当てなど)場合に問題になります。Buddy allocator はこの断片化を軽減するために隣接ブロックを併合する手法を取りますが、長時間稼働したシステムでは断片化が残ることがあります。

大ページ(HugePages)とパフォーマンス

TLBはエントリ数に限りがあるため、ページ数が多いとTLBミスが増えます。大ページ(2MiBや1GiB)を使うと、同じメモリ量を少ないページ数で表現でき、TLB圧力を減らして性能向上が期待できます。LinuxではTransparent HugePages (THP)や事前確保のHugePagesが利用可能ですが、断片化やメモリ使用パターンによるトレードオフがあります。

NUMA(非一様メモリアクセス)

マルチソケットシステムでは、CPUソケットごとにローカルなメモリがあり、ローカルアクセスの方が高速な場合があります(NUMA)。OSはプロセスとメモリ配置をできるだけローカルに保つことで遅延を低減します。NUMAを無視したメモリ配置はスループット低下や予期せぬボトルネックを招きます。

セキュリティと実体メモリ

  • メモリ分離:各プロセスの仮想空間はハードウェアとOSの協調により分離されています。物理メモリはMMUとページテーブルを通じてアクセス制御されます。

  • 未初期化メモリの問題:メモリを割り当てた際にクリアしないと古いデータが残る可能性があるため、カーネルやランタイムは機密性のためにゼロ化することがあります。

  • Rowhammerなどのハードウェア脆弱性:DRAMの物理特性を悪用して近傍ビットを書き換える攻撃が報告されています。ハードウェア・ファームウェア・ソフトウェアの対策が重要です。

実体メモリの計測と監視(Linuxを例に)

システム管理者は物理メモリの状態を監視してボトルネックやリークを発見します。代表的なコマンド:

  • free -h:総メモリ、使用中、空き、バッファ/キャッシュ、スワップ情報。

  • cat /proc/meminfo:詳細なメモリ統計(MemTotal、MemFree、Buffers、Cached、SwapTotal、SwapFree、Active/Inactiveなど)。

  • vmstat、sar、top、htop:メモリとCPUのリソース使用を継続的に監視。

  • perf、ebpfベースのツール:ページフォールト、TLBミス、キャッシュミスの詳細な分析に有用。

運用上のベストプラクティス

  • 十分な物理メモリを搭載する:ディスクスワップに頼ると性能が大幅に悪化するため、ワークロードに応じてメモリ容量を見積もる。

  • メモリプロファイリング:アプリケーションの実メモリ使用量(RSS)と仮想メモリ使用量を監視し、メモリリークを早期に検出する。

  • NUMAを考慮する:マルチソケット環境ではプロセス・スレッドとメモリのローカリティを調整する。

  • HugePagesの適切な利用:データベースなどTLB耐性の高いワークロードではHugePagesが有効。ただし断片化や管理上のコストに注意。

  • セキュリティ対策:不要な物理メモリ共有を避け、カーネル/ファームウェアの脆弱性に注意する。

トラブルシューティングのヒント

  • メモリ不足が疑われる場合は /proc/meminfo を確認し、スワップ使用量やページアウト率をチェックする。

  • ページフォールトが多い場合はページキャッシュの効果やアクセスパターン(ランダム/シーケンシャル)を見直す。

  • TLBミスやキャッシュミスが多ければアプリのメモリアクセスパターンや大ページ導入を検討する。

  • 断片化が原因で大きな連続物理メモリが割り当てられない場合は再起動やメモリ圧縮、事前確保の戦略を検討する。

まとめ

実体メモリはシステム性能と安定性に直結する重要なリソースです。ハードウェア(DRAM、MMU、IOMMU)とOS(ページテーブル、アロケータ、スワップ、ページキャッシュ)が協調して実体メモリを扱います。性能最適化や問題解決には、仮想→物理変換の仕組み、TLB/キャッシュの影響、NUMAやHugePagesなどの特性を理解しておくことが不可欠です。

参考文献