memory
基礎
- 記憶領域
- CPU に渡す処理内容やデータを保存したり、処理結果を受け取ったりする
- 揮発性のためサーバの再起動が行われると情報がなくなる
- メモリインタリーブ
主記憶へのアクセスを高速化するための技法
- 先読みを行いあらかじめデータを CPU におくっておきレイテンシーを軽減する
- CPU からメモリーへのアクセスを高速化するために、メモリー内部を複数のバンクに分割し、各バンクを並列にアクセスする
- 物理上は 1 つであるメモリー領域を、同時アクセス可能な複数の論理的な領域(バンク)に分け、これに並列アクセスすることで見かけ上のアクセス時間の短縮を図るメモリアクセス高速化技術
物理メモリ
- 管理機能
- PC が搭載している物理メモリを
ページ
という小さな固定長ブロックに分割して管理 - 物理メモリ領域をエリア分け
- ZONE_HIGHMEM
- 主にカーネル以外のアプリケーションプログラムやアプリケーションデータを格納する領域
- ZONE_NORMAL
- カーネルを含めたプログラムやデータを格納する領域
- ZONE_DMA
- 周辺機器とのデータのやり取りのために使用する領域
- カーネル領域としても利用できる
- ZONE_HIGHMEM
- カーネル内プログラムが物理メモリを利用しやすくなる仕組みを用意
- Buddy システム
空きメモリ領域を高速に割り当て可能にする仕組み
空きメモリ領域の管理状況
# cat /proc/buddyinfo Node 0, zone DMA 221 112 10 1 0 0 0 0 0 0 0 Node 0, zone DMA32 5940 6263 3516 869 65 7 0 0 0 0 0
- スラブアロケータ
- カーネル内で使用するデータ構造用にスラブ(フリーサイズのメモリ領域) を高速に割り当て仕組み
- 構造体と呼ばれるデータ構造のメモリー領域を高速に確保できるようにする
- Buddy システム
- PC が搭載している物理メモリを
仮想メモリ(仮想記憶)
- プロセスそれぞれにメモリ空間が存在
- 単位は
ページ
- プロセスが仮想メモリーを利用する分だけ、ページ単位で物理メモリーから割り当てる
- 同じアドレスであってもそれが指し示す物理ページは異なるので、メモリの重複がないし、別の仮想メモリのデータにアクセスすることも不可
- 仮想的なアドレスと物理的なアドレスの対応関係が書かれた表を
アドレス変換テーブル
といい、この変換処理は MMU と呼ばれるハードウェアによって行われる
- 単位は
ページング
- 仮想アドレス空間を
ページ
と呼ばれる固定長の区画に分割,同時に主記憶上も同じように固定長に分割して、このページ単位で主記憶と補助記憶装置のアドレス変換を行う方式 - ページング方式の特徴からプログラムに割り当てるメモリが連続である必要はなく、大きなフラグメンテーションがほとんど発生しないため、メモリを無駄にしないという利点がある
- プログラムやデータを分割して記憶領域を管理しコンピュータの仮想記憶を実現するための方式
- ページングでは、仮想記憶と主記憶間のデータの受け渡しをページという固定長の単位で行いますが、このページのやり取りは「ページフォールト(ページがメモリ上に存在しないこと)が発生したときに主記憶のどのページを置換えるか」および「どのページをどのタイミングで主記憶に読み込むか」という二つのアルゴリズムに基づいて管理が行われます
- 前者の置換え対象を決定する方法
- LRU(Least Recently Used)
- FIFO(First In First Out)
- FIFO(First In First Out)","最初に記憶したページを追い出す
- LFU(Least Frequently Used)
- 参照頻度が最も少ないページを追い出す方式
- 後者の読込み対象と読込むタイミングを決定するアルゴリズム
- デマンドページング方式
- アクセス要求があった時に要求があったページのみを主記憶に割り当てる方式
- メモリ使用量の節約,プログラム開始時の主記憶へのロードによる遅延がない,ページの読込みが最小限で済むなどの利点があり、実際のOSでは基本的にこの方式が用いられている
- ページフォルトの発生率は高くなる
- プリページング方式
- ページにアクセス要求がある前に、前もって参照されそうなページを主記憶に読み込んでおく方式
- アクセス要求があった時に周辺のページも同時に主記憶に読み込んだり、プログラムのロード時にたくさんのページを読み込んでおくことで、メモリ使用量は増加するがメモリアクセスの効率を向上させることができる
- デマンドページング方式
- 仮想アドレス空間を
空きメモリの調査
- free コマンド
- ページ回収
キャッシュを解放して空きメモリーにすること
キャッシュ追い出し
# sync # echo 3 > /proc/sys/vm/drop_caches
- ディスクに書き込まれていないファイルを持つページキャッシュを解放しないように
sync
コマンドを実施する
- ディスクに書き込まれていないファイルを持つページキャッシュを解放しないように
キャッシュの削除でも足りない場合には物理メモリのデータを HDD などに用意した スワップ領域に一時的に退避させる
- ページアウト、スワップアウト
- => 逆はぺーじイン、スワップイン
スワップでも対処できない場合には OOM(Out Of Memory) Kiler が発生する
/proc/PID/smaps
を見ると CoW で親子が共有しているメモリのだいたいのサイズが分かるCoWとはコピーオンライト機能によりメモリを一部共用
cat /proc/29917/smaps| head 08048000-0941a000 rwxp 00000000 fb:00 147635 /usr/bin/skype Size: 20296 kB Rss: 20296 kB Pss: 20165 kB Shared_Clean: 196 kB Shared_Dirty: 0 kB Private_Clean: 0 kB Private_Dirty: 20100 kB Referenced: 20296 kB Swap: 0 kB
- smaps では共有領域のサイズは Shared、そうでない領域のサイズは Private として報告
cat /proc/29917/statm Provides information about memory status in pages. The columns are: 77878 size total program size 23470 resident resident set size 5596 share shared pages 5074 text text (code) 0 lib library 35454 data data/stack 0 dt dirty pages (unused in Linux 2.6) PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 29917 takahash 20 0 304m 91m 21m S 1 0.8 0:52.28 skype
- 4kB を掛けたものが top の SHR カラムの値
- CoW で共有される領域は Shared_Dirty
- 共有されていないプライベートデータは Private_Dirty
カーネル仮想空間
- カーネルが使用するメモリー空間をプログラムの仮想メモリ空間にマッピングしたもの
メモリーマップ
- プログラムがどのように仮想メモリ空間を使用しているかの情報
/proc/${PID}/maps
を見る
- マイナーページ
- 物理ページは存在するが、ページテーブルのページフォールトを発生させた仮想アドレスに対応するエントリに登録されていない状態
- OS のページフォールト・ハンドラは単にその物理ページを問題のページテーブルエントリに登録すればよく、二次記憶装置から物理メモリに内容を読み込む必要はない。このような状況は例えば共有メモリを使っていて、共有する相手側プログラムが先に共有メモリにアクセスし、物理メモリ上に内容が存在している場合に起きる。プロセスのワーキングセットからページを削除した場合も、ディスクに書き戻して消去するまでそのページはキャッシュとして保持され、同様の状況になりうる。例えばOpenVMSはワーキングセットが大きすぎると判断すると、ディスクに書き戻す必要のないページ(ディスクから読み込んだ後、一度も内容を変更されていないページなど)を除去し、フリーなページのリストにつなぐ。しかし、そのページを別の用途に再利用するまで内容はそのまま保持されるので、もともとそのページを使用していたプロセスがそのページの対応していた仮想アドレスを参照すると、マッピングを元に戻すことが可能である。マイナーなページフォールトではディスクアクセスが発生しないので、高速に処理できる。
- メジャー
- ページフォールト発生時、問題のページがメモリ上にロードされていない場合。OSのページフォールト・ハンドラはフリーな物理ページを探し、なければ現に使われているページから再利用する物理ページを選ぶ。選択した物理ページの現在の内容が二次記憶装置に書き戻されていない場合、書き戻して完了を待つ必要がある。そして、必要なページ内容を二次記憶装置からその物理ページに読み込む。ここまで処理すると、やっとマイナーなページフォールトと同じ状況になり、後の処理は同じである。二次記憶装置の入出力を待ち合わせる必要があるため、メジャーなページフォールトを起こしたプログラム(プロセス)は即座に処理を再開することはできない。仮想記憶で物理メモリ容量以上のメモリ要求に対応できるのは、この機構のおかげである。
RAN(Random Access Memory)
- 揮発性メモリ
- DRAM(Dynamic Random Access Memory)
- コンデンサに電荷を蓄えた状態か否かによって 1 ビットを表現
- 主記憶としてよく使用される
- SRAM とくらべて速度は劣るが、構造が単純でビットあたりの面積を小さく出来るので安価に高集積化(大容量化)が可能
- 周期的にデータの再書き込み(リフレッシュ)が必要
- 電源のない状態で記憶内容を保持することが不可
- 価格
- 安い
- 容量
- 大きい
- リフレッシュ
- 必要
- 速度
- 遅い
- SRAM(Static RAM)
- 価格
- 高い
- 容量
- 小さい
- リフレッシュ
- 不要
- 速度
- 早い
- 価格
ROM(Read Only Memory)
- 不揮発性メモリ
- マスク ROM
- 最初からデータが書き込まれていて内容が変更できない
- PROM(Programmable ROM)
- ユーザがデータを書き込んだり、削除したりできる
- 一度だけ書き込み可能だったり、何度でも可能なものがある
- EPROM(Erasable PROM)
- 紫外線でデータを消去
- EEPROM(Electrical Erasable PROM)
- 電気的にデータを消去
SODIMM(Small Outline Dual In-line Memory Module)
- ノートパソコン向けのメモリ
microDIMM
- ノートパソコン向けのメモリ
- SODIMMより小さめ
- CPU と主記憶の間に置かれるキャッシュメモリの書き換え方式
メモリインタリーブ
- メインメモリをバンクと呼ばれる複数の区画に分割。この複数の区画には同時にアクセスすることが可能。
キャッシュメモリの利用
- ヒット率
- データががキャッシュメモリ上に存在する確率[<->NFP(Not Found Probability)]
- ヒット率 + NFP = 1
- ヒット率
平均アクセス時間 = ヒット率 × tc(キャッシュメモリへのアクセス時間) + (1 - ヒット率) × tm(主記憶装置へアクセス時間)
キャッシュメモリの割り当て
- ダイレクトマッピング
- メインメモリのブロックをキャッシュメモリの決められた場所に割り付ける方法
- 割り当てが単純な分、キャッシュミスが多くヒット率が低くなる
- フルアソシアティブ
- メインメモリのブロックをキャッシュメモリのどの場所にもでも割り付けるようにする方法
- 実際にはアドレス変換が複雑になり実現は難しい
- セットアソシアティブ
- ダイレクトマッピングとフルアソシアティブを折衷した方式
- メインメモリのブロックを決められたセット内においてどこにでも割り付けるようにする方法
- ダイレクトマッピング
- バルーニング
- 仮想マシンで未使用のメモリを確保しているサーバからメモリを解放して、別の仮想マシンに割り当てる機能
ボトルネック
- 領域不足
- メモリ不足でスワッピングが発生
- 同一領域への競合
vmpressure 機能
- メモリ回収処理の負荷に応じてユーザに通知される機能
- memory cgroup
kswapd
- 利用されてないメモリを回収したり、メモリを swap に掃き出してメモリの量を回復する機能
メモリの圧縮
- 空きメモリが必要になった場合にはデータを捨てるか退避する必要があったが、CPU を使ってデータを圧縮することで空きメモリを作り出す機能が用意
zram
- 物理メモリの一部を「圧縮・伸張機能を搭載する RAM ディスク(仮想ディスク)」 に仕立てる機能
tmpfs
などの代替として用いることによってメモリ消費量を抑えられる
zswap
- スワップの確認
/proc/swaps
# cat /proc/swaps Filename Type Size Used Priority /dev/dm-1 partition 1048572 0 -1
アプリケーションプログラムをロードしたメモリ領域の内部構造
テキストセグメント
プログラムの命令
が格納される領域- 機械語のプログラムが格納され、そのプログラムを CPU が読み込みながら実行
データセグメント
- データを格納するセグメント
- 3 つの領域に分かれる
- 定数領域
- 静的変数領域
- 動的に確保されるヒープ領域(C 言語の malloc 関数)
スタックセグメント
- プログラムを実行するときに動的に利用される領域
- 一時的なもの
- スタック