『Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識』第5章[前編]

第5章 メモリ

はじめに

参考文献

武内 覚 著『Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識』をテキストとして学習した記録です。

本書を読んで筆者が解釈した内容について記述しています。

なので本書の内容の間違った解釈やあるいは単純に間違った記述がある可能性があります。

概要

Linuxのメモリの扱い方

誰がメモリを管理しているか

メモリの使用状況はカーネルのメモリ管理システムが管理している。

メモリを管理しているのはカーネルだが、メモリを使用するのはプロセスだけではなくカーネル自身もまたメモリを使用している。また、カーネルが使用しているメモリ領域のデータは捨てても良いものか捨てることができない重要なものかはカーネル自身が知っているが、プロセスのそれはカーネルからは判断することができない。

メモリが足りなくなってくるとカーネルはメモリ領域のうちで捨てても大丈夫だとわかっているカーネル由来のデータを破棄するが、それでもメモリが足りなくなってきた場合OOMと呼ばれる状態になる。

こうなるとシステムは何もできない状態になってしまうため、メモリを使用しているプロセスをランダムにkillすることでメモリを解放するOOM killerを発動する。

サーバで勝手にこのようなことをされると困るのでOOM発生時はシステム全体を強制終了させる設定を行う場合もある。

どうやってメモリを割り当てるか

これまででわかっているところ

  • メモリを管理するのはカーネルのメモリ管理システム
  • メモリを使うのはプロセスとカーネル
  • メモリは有限
  • メモリは皆で同時に分け合って使われている

プロセスはカーネルに自分の分のメモリの割り当てを要求する。

プロセスの割り当ては下記のように行う

  1. カーネルがプロセスにとって必要な分のサイズのメモリを確保する
  2. その先頭のアドレスをプロセスに渡す

プロセスは生成された時点で一旦メモリをもらうが、そのあとでメモリが足りなくなったら追加の分を要求する。

プロセスがメモリ上の自分用の領域を使いたい場合にはカーネルにもらったアドレスを基準にメモリの参照や書き換えなどを行う。

上記のようにプロセスが直接本物のメモリにアクセスできるような設計には問題がある。

  • 離ればなれのアドレスにあるメモリを一つのプロセスが扱うのは困難
  • 自分の領域ではないアドレスにアクセスすることが可能
  • マルチプロセスを実行したいときにアクセスすべきアドレスがわからなくなる

仮想記憶

プロセスにメモリへ直接アクセスさせる際の問題点を解決するための仕組みが仮想記憶。

Linuxではプロセスには直接本物のメモリ上のアドレスにアクセスさせる代わりに仮想記憶を介してアクセスさせるようにしている。

メモリ上の本物のアドレスのことを物理アドレスとよび、プロセスが認識するアドレスを論理アドレスと呼ぶ。

プロセスは論理アドレスを指定してメモリを読み書きするが、実際に扱うアドレスは論理アドレスに対応する別のアドレスということになる。

ページテーブル

どの仮想アドレスがどの物理アドレスに対応しているかはカーネルが使用・管理しているメモリ領域の「ページテーブル」というテーブルに記録されている。

プロセスが論理アドレスを指定するとCPUがそのプロセスのページテーブルを見て対応する物理アドレスを探し、そこにアクセスするようにする。

またページテーブルにはそのプロセスに割り当てられているだけの領域しか記録されていないはずなのでプロセスがその領域外の論理アドレスを指定した場合はページフォールトという割り込み処理が発生し、そのプロセスの処理を不正な処理とみなした上で強制終了するようになっている。