こんにちは。
前回はイントロダクションで終わってしまいましたが、
今回は『大容量メモリに潜むメモリの枯渇問題』のよくある原因について早速ご紹介していきます。
ページテーブルエントリ
大容量メモリにおけるメモリ枯渇問題のよくある原因の1つは、「ページテーブルエントリ(以下、PTE)」です。
PTEはメモリ上に確保される要素であり、OS(ここではLinux)がメモリ管理を行ううえで重要な役割を担います。しかし、このPTEが予想外のメモリ消費を引き起こすことがあります。
ではまず、PTEを理解するうえで前提となるページテーブルについて説明します。
物理メモリは、「ページ」という一定サイズで切り出した単位で管理されており、x86CPUを使用したLinuxの場合、1ページあたりのサイズが4KBとなっています。実に、1GBのメモリ領域でも26万ページ以上のページ数になります!
通常、プロセスからメモリ領域へのアクセスに使用されるアドレスは仮想アドレスです。
この仮想アドレスが最終的に物理アドレスに変換され、メモリ上のデータを読み込むことが可能となります。
この「仮想アドレス⇒物理アドレス」のマップ情報は、メモリ上※に記録されており、この情報をページテーブルといいます。
※CPUキャッシュの一部であるTLBも重要な要素ですが、一先ずここでは割愛します。
先ほどの1GB/26万ページの変換情報もこのテーブル内に記録されていますが、当然、1ページずつ記録していては広大なメモリ領域を必要とします。更に、メモリアクセスのたびに全マップ情報を検索していては非常に非効率です。そのため、ページテーブルはインデックス(OracleのB*Tree索引と似た構造)による階層管理となっており、この階層要素のひとつにPTEが含まれています。
ページテーブル内のインデックスは、仮想アドレスを9bit単位の4分割(計36bit)で管理しており、1分割単位で仮想アドレスと物理アドレス間のアドレッシングを行っています。最終的に12bitのオフセットアドレス(この12bitのオフセットについては仮想アドレス、物理アドレスの間で変化しません)を加算し、物理アドレスを解決しています。
図2. 仮想アドレスの分割
※x86CPUでは、64bitアドレスをハードウェアの制限から行えず、48bit表現(256TB)となっています。
このようなページテーブルのエントリー方式が、デフォルトの設定となっいます。
次回からは、これが今日のような巨大なメモリ領域を使用する場合にどのような影響を及ぼすのか、具体的に追っていきたいと思います。