計算機システム II ・第 14 回

計算機システム II ・第 14 回
2016 年 1 月 7 日
今回の内容
14.1 ユーザープロセスへのメモリ割り当て . . . . . . . . . . . . . . . . . . . . . . .
14.1
14 – 1
ユーザープロセスへのメモリ割り当て
ユーザープロセスが起動した際には、その実行に必要な
メモリ空間がカーネルによって割り当てられます。たと
仮想アドレス
0
テキスト領域
えば、Linux などの Unix 系 OS のユーザープロセスのア
(機械語プログラム)
ドレス空間は、たとえば右の図のようになっています1 。
データ領域
(初期化されたデータ)
テキスト領域 機械語プログラムや、そのプログラムが使
用する読み取り専用のデータ2 が置かれます。テキス
BSS領域
トセグメント (text segment) やテキストセクション
(0 で初期化されたデータ)
(text section) と呼ばれることもあります。この領域
³
は読み取り専用で、プログラムの実行中に書き変わる
ヒープ領域
実行中に動的に確保
されるデータ領域
´
..
.
ことはありません。同じプログラムが複数起動される
場合は、その複数のプロセス間で同じ物理ページが共
有されます3 。
..
.
データ領域 プログラムで使用される初期値を持つデータ
mmap 用領域
のための領域です。 C プログラムの静的変数4 が 0 以
外の初期値で初期化される場合、この領域に割り当て
スタック領域
られます。データセグメント (data segment) やデー
タセクション (data section) と呼ばれることもありま
す5 。 この領域は読み書きがともに可能で、同じプロ
³
?
カーネルが
使用する領域
´
グラムが複数起動されている場合でも、独立した物理
ページが使用されます。
BSS 領域 BSS セグメント (bss segment) や BSS セクション (bss section) と呼ばれることもあり
ます。 0 で初期化されるデータのための領域です。 C 言語の静的変数が 0 で初期化されている
場合6 、この領域に割り当てられます。
1
OS によっては mmap 用領域がスタック領域の後に取られる場合もあります。
2
たとえば、C プログラムの文字列リテラル (文字列定数) など。
3
Unix 系 OS で採用されているデマンドページング方式の仮想記憶システムの働きです。
4
大域変数 (関数定義の外で宣言される変数や配列) や、static というキーワード付きで宣言される局所変数 (関数定
義やブロックの内部で宣言される変数や配列) のことです。
5
BSS は Block Started by Symbols の頭文字で、あるアセンブリ言語において、特定のメモリ領域を名前を付けて
予約するための疑似命令 (アセンブラーへの指示) の名前に由来します。
6
C 言語では、初期値を特に指定せずに静的変数を宣言すると、その変数 (や配列) は 0 で初期化される決まりとなっ
ています。
14 – 1
ヒープ領域 プログラムの実行中に、必要に応じてメモリが割り当てられる領域です。 Unix 系 OS
では、sbrk や brk と言ったシステムコールを呼び出して、この領域の終りを変更することがで
きます。C 言語の標準ライブラリに含まれる malloc や calloc などの関数は、動的に (プログ
ラムの実行中に) メモリを割り当てることができますが、これらの関数は、このヒープ領域を拡
張することで必要な領域を確保し、そこからメモリ割り当てを行います7 。
mmap 用領域 Unix 系 OS には、その仮想記憶システムの一部として、ファイルの内容の一部を仮
想アドレス空間の一部に対応させて、ユーザープロセスがメモリの読み書きを行うことで、ファ
イルの内容の読み書きを可能にする機能が用意されています。ファイルの内容と仮想アドレス
空間の一部の対応は、mmap というシステムコールを使って作ることができます。ヒープ領域と
後述のスタック領域の間の仮想アドレス空間は、この mmap システムコールを利用して、ファイ
ルの一部を仮想アドレス空間に対応付けするのに使用されます。
実行中のプログラムが使用しているライブラリの機械語プログラムや、そのライブラリプロ
グラムが使用するデータもこの領域に置かれます。ユーザープログラムがライブラリを使用す
る場合は、この mmap システムコールで、ライブラリファイルの一部を仮想ページに対応させる
ことで、ライブラリの機械語プログラムをユーザープロセスのアドレス空間に取り込みます。
また、mmap は名前のない新しいファイル8 を仮想アドレス空間に対応させることで、読み書き可
能な新しいメモリ領域を確保することができますので、ライブラリ関数が使用するデータ領域
はこの機能を利用して確保されます。
スタック領域 実行中のプログラムがサブルーチンの呼び出しを行う際のリターンアドレスや、呼
び出されたサブルーチンなどが一時的に使用する記憶領域が置かれます。 C プログラムの自動
変数9 は、このスタック領域に割り当てられます10 。プロセスの起動時には、スタック領域はほ
とんど使用されていませんが、サブルーチンの呼び出しの入れ子が深くなるにつれて、必要な
記憶領域が大きくなっていきます。また、サブルーチンから呼び出し元へ戻る (リターンする)
ごとに必要な記憶領域の大きさが元に戻っていきます。
スタック領域として確保される大きさは、そのプロセスを起動した際に決定されますので、
サブルーチン呼び出しの入れ子が深くなり続けると、いずれはスタック領域を越えてしまい、メ
モリアクセスに関する例外が発生してしまいます11 。
計算機システム II ・第 14 回・終わり
7
これらの関数は、ヒープ領域を使用せずに、(特に大きな領域が必要な場合に) 後述の mmap 領域を使って動的なメ
モリ割り当てを行う場合もあります。
8
前回、ページング方式の仮想記憶システムの節で説明したスワップ領域の一部です。
9
static というキーワードを付けずに宣言された局所変数など。
10
ライブラリ関数 alloca が割り当てるメモリも、自動変数と同様にこのスタック領域に割り当てられます。
11
Unix 系 OS では、この例外はセグメンテーション違反 (Segmentation Violation または Segmentation Fault) と
呼ばれ、シグナルと呼ばれる仕組みでカーネルからユーザープロセスに伝達されます。
14 – 2