オブジェクトプログラミングのメモリ管理
メモリの管理
ごく簡単に。
ヒープ領域:インスタンス、バッファ。
スタック:メソッドに渡す引数など。
静的領域
このメモリ領域は最初にプログラムが記述されたファイルがメモリに読み込まれた瞬間からそれが破棄されるまで大きさや大まかな内容は変化しません。
静的とは文字通り止まっているメモリ領域です。
具体的にはどんなものと言えば、クラスのメソッドとグローバル変数です。
インスタンスがヒープ領域に読み込まれたとしてもそれはメソッドのようなクラスのコード自体を保持することはありません。
既述のようにそれは静的領域に保持されています。
ヒープ領域に配置されたインスタンスは静的領域に置かれたクラスの最初のメモリアドレスも保持します。
インスタンスがメソッドの実行を命じられた場合、設定された引数を持って静的領域のメソッドのある場所へジャンプします。
ややこしいインスタンス変数とグローバル変数の違いはここです。
Staticと修飾されたグローバル変数は静的領域に読み込まれます。
つまりnew(インスタンス化)しなくてもポインタ(メモリアドレス)を取得して呼び出すことができます。
例
具体的にゲームで表現します。
同じような敵が大量に出現するステージを作るとするとHPや攻撃力などは敵(インスタンス)で個々に管理しなければなりません。
個別の情報はインスタンスのインスタンス変数にHPや攻撃力などを設定します。
そして敵の数などクラス全体として管理しなけらばならない数値がグローバル変数です。
敵を倒す度に倒された敵(インスタンス)はクラスのグローバル変数にアクセスして数値を減少させます。
役目を終えたインスタンスのいたメモリは別のインスタンスを設置する為に掃除(ポインタ破棄)されます。
敵(インスタンス)は攻撃命令を受けるとその攻撃方法が記載されている静的領域のメソッドのエリアへ行って攻撃方法を確認します。
そしてその記載されている内容の通りに攻撃動作を行います。
そのため静的領域ではなくメソッドエリアと呼ばれます。
それとは別にC++はC言語との互換性を持たせるために一度にまとめてコードを読み込みます。
ヒープ領域
ヒープ領域はファイルがメモリに読み込まれるときにはどれくらいメモリを使用するか分からないようなデータを格納します。
例えばあるメモ帳(アプリケーション)で文書入力をするために前回作業していたファイルをメモリに読み込むとします。
前回の作業量によってはかなり大きなメモリ領域(バッファ)を必要とします。
しかしメモ帳(アプリケーション)を起動瞬間にはどのどの大きさのファイルを開くかメモ帳は知りません。
他にもプログラムの処理の結果によってはそれを格納するメモリが巨大化する可能性があります。
ゲームなどもステージによっては敵(インスタンス)をプレイヤーのレベルによっては大量に出現させたいことがあるかもしれません。
上記のように動的にメモリの必要量が変化する時、アプリケーションはOSに通知して動的にメモリ領域を確保してもらいます。この動的な領域がヒープ領域です。
繰り返しになりますが敵の行動パターン(メソッド)や敵の数(グローバル変数)は静的領域に配置され、HPや攻撃力、スピードと言った敵(インスタンス)個別に設定するインスタンス変数(フィールド、メンバ変数)はヒープに読み込まれます。
この個別の値を設定してメモリに読み込むことがインスタンス化(インスタンシエイト)と呼ばれます。
つまりインスタンス化とはヒープ領域にインスタンスを定義したり識別する情報をメモリにロードすることです。
インスタンスはnewされた時にメモリのヒープ領域に読み込まれます。
この領域のデータは利用後は言語の仕様により破棄されます。
オブジェクティブ言語でインスタンス化とか割と漠然とした言われ方をされますが、つまりヒープ領域にインスタンスを表現するために必要なデータを読み込むことです。
スタック
ここにはインスタンスのメソッドを実行するときに必要な引数を保存します。
メソッドの命令の先頭へジャンプした後にメソッド内でその引数を取り出して使用します。
他のメモリ領域とはデータの配置の仕方や取り出し方といった扱い方が異なるため、値の小さな数値や引数となるインスタンスへのアドレス、メソッドを実行した後のリターンアドレスなど基本的に小さなデータを扱うための領域です。
コンストラクタ
インスタンス化された時点、つまりnewしてメモリのヒープ領域にインスタンスを構成する変数などが配置されたタイミングで自動的に実行されるメソッドです。
使い方としてはインスタンス化した時に設定しておきたい情報をコンストラクタで付加します。
例えばゲームで同一種類(クラス)の敵(インスタンス)を大量にフィールドに出現させる時、敵ごとに異なる値のHPなどを設定するはずです。
その値を初期化するのがコンストラクタです。
逆に破棄するときに呼び出されるメソッドをデストラクタと呼びます。
他のメモリのページ

コメント