メモ
- システムコールは本来はアセンブリコードで呼び出す。カーネルはシステムコールを呼び出すアセンブリコードのラッパー関数を提供してくれる。これによりC言語からシステムコールを呼び出せる。
- C言語は、glibcを標準ライブラリとしてリンクしている。ここにシステムコールのラッパー関数が含まれている。POSIXという規格に定義されている関数も含まれている。
メモリ
- デマンドページング : メモリ確保系のシステムコールがあったらとりあえず仮想アドレスを割り当てる。CPUが仮想アドレスをを参照したときに初めて物理アドレスが割り当てられる。こうすることで柔軟に効率的に物理アドレスが割り当てられる。プロセスがmmap関数で動的に仮想アドレスを確保した場合も、実際は物理アドレスは割り当てられないで、CPUが参照した時に初めてページフォールトが起きて、カーネルにより物理アドレスが割り当てられる。
- ファイルマップ : プロセスがファイルにアクセスするときは、ストレージのデータがメモリ上にマップされる。マップされたメモリ上のデータを書き換えるとストレージにもその変更が適用される。
ファイルシステムへのアクセスはページ(ブロック)という単位で行われる。(1ページ=4Kb)
ブロックデバイス(ストレージ)へのアクセスはセクタという単位で行われる。(1セクタ51
2バイト)
- コピーオンライト : fork()関数などでメモリをコピーするときに、ページテーブルをコピーして書き込みの時まで物理アドレスの割り当てを遅延させる。ページテーブルをコピーすると複数のプロセスから同じ物理アドレスを参照できるため、デフォルトの状態は参照のみで書き込みはできない。片方のプロセスが書き込みをしようとするとページフォールが発生し、カーネルにより新しい物理アドレスが確保され、コピーされていたページテーブル書き換える。最初はメモリが共有されているが、書き込み後はそれぞれのプロセスで別のメモリを読み書きするようになる。物理メモリを書き込み時にコピーすることからコピーオンライトと呼ばれる。
- スワップ : 物理メモリが足りなくなったときに、ストレージの一部をメモリの代わりとして使う。ストレージの「メモリの一部として使われる領域」をスワップ領域という。仮想メモリにアクセスして物理メモリが足りなかった場合、ページフォールトが発生し、カーネルは「近いうちに使わないであろう」物理メモリのデータをスワップ領域に退避(スワップアウト)させて、物理メモリを確保する。スワップさせているデータを利用するときはカーネルによりスワップ領域のデータがメモリに戻どされる(スワップイン)。スワップインはメモリが空いたタイミングなどでも起こる。スワッピング(スワップアウト、スワップイン)はページ単位で行われるため、ページングとも言う。
- ユーザーモード(プロセスとか)からは物理アドレスに直接アクセスできない。これにより複数のプロセスから同じ物理アドレスにアクセスしてメモリが破壊される心配はなくなる。
- malloc関数は内部でmmap関数を使ってメモリをプールしている。ページ単位ではなくバイト単位でメモリを確保できるようなる。
- メモリの枯渇には仮想メモリの枯渇と物理メモリの枯渇がある。仮想メモリが枯渇した場合、物理メモリがどんなに余っていようとプロセスからはメモリを利用できない。x86_64アーキテクチャでは128TBまで仮想アドレス空間が確保されている。反対に物理メモリが枯渇すると仮想メモリがどんなに余っていようとプロセスからはメモリを利用できない。
- スワッピングのようにストレージへのアクセスが発生するページフォールトをメジャーフォールトと言い、ストレージへのアクセスが発生しないページフォールトをマイナーフォールトと言う。
ファイルシステム
ストレージ上のどこにどんなデータがあるか、どこに空き容量があるかを管理する仕組み。ファイル名を覚えておくだけで、ストレージ上のデータを管理できる。ファイルシステムはデータ自体をデータの位置やサイズなどの補助的な情報を付加した上でファイルという単位で管理する。また、ファイルの作成、削除、読み書きなどの機能を提供する。
補足