google-code-prettify

2008-05-16

BSS領域はだれが0クリアしているのか? - 答え

答えは、
1. カーネルが、プログラムのロード時に行う。

なぜカーネルが行っているかの理由はわからないが、ユーザーランドの初期化ルーチンが0クリアするよりも、カーネルが行うほうが圧倒的に効率がよい。
以下、なぜ効率がよいかの説明。




プロセスがロードされるとき、メモリに一度に全てロードされるわけではない。
ページと呼ばれる4KBの塊ごとに分割され、アクセスがあったページだけがメモリにロードされる。
(これを、demand-pagingと言う)
このdemand-pagingにより、プロセスの起動時間の短縮と、必要なメモリ量の低減が実現できる。

プロセスが初期値0の変数にアクセスすると、その変数が存在するページ4KBだけがメモリに割り当てられる。
その際、カーネルが0クリアしたページが割り当てられる。


もしユーザーランドの初期化ルーチンが0クリアするとなると、
memset(bssarea, 0, bssarea_size);
を実行することになる。

このmemsetはBSS領域の全ての領域にアクセスすることになる。
すなわち、一度全ての領域をメモリにロードしてしまうことになり、
demand-pagingの恩恵が受けられない。

2 件のコメント:

匿名 さんのコメント...

BSSのゼロクリアの必要性は、他のプロセスが書き込んだ内容を新しいプロセスが読めないようにするためだったと聞いたことがあります。例えばパスワード文字列とか。
その場合、カーネルがクリアしてあげないといけない気がしますが、それがカーネルがクリアする理由だと思います。

sakurai さんのコメント...

なるほど。言われてみれば確かにその通りですね。
謎が解けました。ありがとうございます。