2012年05月16日

メモリイメージ

日に日に気温も上昇し汗ばむ季節になってきましたね晴れ
汗かきなので既に薄着になりつつある「オクダ」です。
皆さんは夏に向けてのカラダ作りは大丈夫ですか?
今年はプロジェクトが佳境を迎えるのであきらめムードですふらふら

今回はプログラマ向けの少しディープな話をしてみようと思います。
テーマは「メモリ」です。
皆さんがPCを使ったりプログラムをしている時にメモリを意識する事は少ないかもしれませんが、
メモリとうまく付き合っていく事で、更に上位レベルのプログラマになれると思います。
プログラムの最適化や言語仕様の理解、デバッグに役立つと思います。

C言語(C++)を基準に解説していきますが、他の言語でも共通する考え方だと思います。
OSやライブラリはの大部分はC(C++)で作られているのでほとんどの言語がCのメモリ管理を踏襲しています。
CPUやコンパイラによる細かな違いもありますが、大きくは変わらないでしょう。


プログラムがシステムからメモリ上にロードされ動作を開始するタイミングでは大きく分けて4つのメモリ領域が確保(割り当て)されます。

1プログラムの命令部分
CPUはここに書かれた命令を一つずつ順番に処理していきます。
稀に、この領域に固定の値が含まれる事があります。(関数のstatic constなローカル変数など)

2固定された値
constな変数がここに分類されます。
固定のテーブルなどはココです。
この領域の内容が書き変わる事は無いハズですね。

3変数領域
globalな変数の領域です。
関数内のstatic変数やC++のstaticなクラスメンバもココになります。
関数内のstatic変数はコンパイラや最適化具合によって1の内部に分散格納される場合もありますが、場所の問題であって意図としては同じです。


4スタック
謎の領域「スタック」です。
基本的に固定された領域ですが、使い方がトリッキーで詳しく説明されない事も多いです。
次回はココにスポットを当てたいと思います。

更に実行時に割り当てられるメモリがあります。

5ヒープ領域
mallocやnewなどで実行時に動的に割り当てられるメモリ領域です。
mallocの場合はメモリ確保のイメージがあると思いますが、
newの場合はメモリ確保している印象は希薄だと思います。
また、関数内で宣言したクラスは宣言タイミングでヒープからメモリ確保され、スコープを抜けるタイミングで解放されます。
constructor,destructor(new,delete)がその都度呼ばれている事に注意しないと痛い目を見ます。

自分がプログラムの中で書いたコードや確保したメモリが
どういった役割を持っていて、どのような場所に確保されているか、、、
少しだけイメージできたでしょうか?
値が変更される可能性があるのか無いのか。
静的に確保されるのか動的に確保されるのか。
このあたりの違いがカギになっているようです。
バグが発生した場合の解決の糸口になる事もあるので、少しだけ意識してみるといいでしょう。

さて、今まで説明してきた中で触れていないモノがあります。
「staticでないローカル変数」です。
最適化された場合にはメモリではなくレジスタに割り当てられることも多いですが、
実は4のスタックに確保されることがほとんどです。
また、レジスタに割り当てられたとしてもスタックと無縁ではありません。
むしろ密接に関係しています。
次回はこの「スタック」の役割と仕組み、動作にスポットを当てたいと思います。
乞うご期待!


posted by 管理人 at 16:19 | プログラミング