オブジェクト指向言語のメモリ管理

オブジェクトプログラミングのメモリ管理

メモリの管理

ごく簡単に。

静的領域:グローバル変数、命令コード。
ヒープ領域:インスタンス、バッファ。
スタック:メソッドに渡す引数など。

静的領域

このメモリ領域は最初にプログラムが記述されたファイルがメモリに読み込まれた瞬間からそれが破棄されるまで大きさや大まかな内容は変化しません。
静的とは文字通り止まっているメモリ領域です。

具体的にはどんなものと言えば、クラスのメソッドグローバル変数です。
インスタンスがヒープ領域に読み込まれたとしてもそれはメソッドのようなクラスのコード自体を保持することはありません。
既述のようにそれは静的領域に保持されています。
ヒープ領域に配置されたインスタンスは静的領域に置かれたクラスの最初のメモリアドレスも保持します。
インスタンスがメソッドの実行を命じられた場合、設定された引数を持って静的領域のメソッドのある場所へジャンプします。

ややこしいインスタンス変数とグローバル変数の違いはここです。
Staticと修飾されたグローバル変数は静的領域に読み込まれます。
つまりnew(インスタンス化)しなくてもポインタ(メモリアドレス)を取得して呼び出すことができます。

具体的にゲームで表現します。
同じような敵が大量に出現するステージを作るとするとHPや攻撃力などは敵(インスタンス)で個々に管理しなければなりません。
個別の情報はインスタンスのインスタンス変数にHPや攻撃力などを設定します。
そして敵の数などクラス全体として管理しなけらばならない数値がグローバル変数です。
敵を倒す度に倒された敵(インスタンス)はクラスのグローバル変数にアクセスして数値を減少させます。
役目を終えたインスタンスのいたメモリは別のインスタンスを設置する為に掃除(ポインタ破棄)されます。

敵(インスタンス)は攻撃命令を受けるとその攻撃方法が記載されている静的領域のメソッドのエリアへ行って攻撃方法を確認します。
そしてその記載されている内容の通りに攻撃動作を行います。

静的領域の大きさは変化しないと書きましたが、JAVAなどの言語は命令が呼び出される度にコードをメモリに読み込みます。
そのため静的領域ではなくメソッドエリアと呼ばれます。
それとは別にC++はC言語との互換性を持たせるために一度にまとめてコードを読み込みます。

ヒープ領域

ヒープ領域はファイルがメモリに読み込まれるときにはどれくらいメモリを使用するか分からないようなデータを格納します。
例えばあるメモ帳(アプリケーション)で文書入力をするために前回作業していたファイルをメモリに読み込むとします。
前回の作業量によってはかなり大きなメモリ領域(バッファ)を必要とします。
しかしメモ帳(アプリケーション)を起動瞬間にはどのどの大きさのファイルを開くかメモ帳は知りません。
他にもプログラムの処理の結果によってはそれを格納するメモリが巨大化する可能性があります。
ゲームなどもステージによっては敵(インスタンス)をプレイヤーのレベルによっては大量に出現させたいことがあるかもしれません。
上記のように動的にメモリの必要量が変化する時、アプリケーションはOSに通知して動的にメモリ領域を確保してもらいます。この動的な領域がヒープ領域です。
繰り返しになりますが敵の行動パターン(メソッド)や敵の数(グローバル変数)は静的領域に配置され、HPや攻撃力、スピードと言った敵(インスタンス)個別に設定するインスタンス変数(フィールド、メンバ変数)はヒープに読み込まれます。

この個別の値を設定してメモリに読み込むことがインスタンス化(インスタンシエイト)と呼ばれます。
つまりインスタンス化とはヒープ領域にインスタンスを定義したり識別する情報をメモリにロードすることです。
インスタンスはnewされた時にメモリのヒープ領域に読み込まれます。

この領域のデータは利用後は言語の仕様により破棄されます。

オブジェクティブ言語でインスタンス化とか割と漠然とした言われ方をされますが、つまりヒープ領域にインスタンスを表現するために必要なデータを読み込むことです。

スタック

ここにはインスタンスのメソッドを実行するときに必要な引数を保存します。
メソッドの命令の先頭へジャンプした後にメソッド内でその引数を取り出して使用します。
他のメモリ領域とはデータの配置の仕方や取り出し方といった扱い方が異なるため、値の小さな数値や引数となるインスタンスへのアドレス、メソッドを実行した後のリターンアドレスなど基本的に小さなデータを扱うための領域です。

コンストラクタ

インスタンス化された時点、つまりnewしてメモリのヒープ領域にインスタンスを構成する変数などが配置されたタイミングで自動的に実行されるメソッドです。

使い方としてはインスタンス化した時に設定しておきたい情報をコンストラクタで付加します。
例えばゲームで同一種類(クラス)の敵(インスタンス)を大量にフィールドに出現させる時、敵ごとに異なる値のHPなどを設定するはずです。
その値を初期化するのがコンストラクタです。

逆に破棄するときに呼び出されるメソッドをデストラクタと呼びます。

他のメモリのページ

コンピューターの主記憶装置管理(メモリマネージメント)
主記憶装置(メインメモリ) メインメモリ wikiの説明です。 コンピュータのメインバスなどに直接接続されている記憶装置で、レイテンシやスループットは速いが比較すると小容量である。 wiki ウィキペディアです。 レイテンシ...


オブジェクト指向でなぜつくるのか 第2版


オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方

プログラミングおすすめ書籍

おすすめ書籍

なぜプログラムが動くのか。
平易な言葉で学べますが、初心者には難しいかもしれません。
でも読み終わった頃にはなんとなく理解しているでしょう。
初心者には家にあって損はありません。

UNIXの思想を学べます。
高尚なタイトルですが、コードはおろか難しい言葉も殆どありません。取っ掛かりに最適でその後のプログラミングに対する理解を一変させます。
なぜならこの思想はプログラミングそのものだからです。
一読の価値ありで、これは良書なので今後紹介したいと思っています。

まだまだありますがまたの機会に紹介したいと思います。

コンピューター 勉強
スポンサーリンク
himazinをフォローする
私の頭の上の消しゴム

コメント

タイトルとURLをコピーしました