作成日 2007/11/12
最終更新日 2009/8/9
オブジェクトが破棄されるタイミング
ここでは、オブジェクトの破棄について説明します。
VB6.0やVBAではnewステートメントを使用してオブジェクトを生成することができます。生成したオブジェクトがいつのタイミングで破棄されるのかを説明します。
また、他の言語では誰がいつのタイミングでオブジェクトを破棄するのかについても簡単に説明します。
C/C++ではオブジェクトの破棄は自動では行ってくれません。破棄するコードをプログラマが記述する必要があります。
Cならfree関数、C++なら、deleteをする必要があります。
…でも、破棄するコードを記述し忘れることが良くあります。
だって、破棄するコードを記述してなくても、プログラムは動いてしまいますので…。
■破棄し忘れるとどうなるか?(メモリリークするとどうなるのか)
プログラム起動後、すぐに終了するプログラムの場合、まず問題は起きません。
一般的にはプログラム終了後にOSが解放してくれますので。(OSがない場合は知らないです。)
じゃあ、サーバのようにプログラム起動後、すぐには終了しないプログラムの場合はどうかと言うと…、使用できるメモリが徐々に減っていき、システムが不安定になっていきます。そのうちメモリの取得が出来なくなります。詳細はWikipediaを参照願います。
■メモリリークを調べるツールは?
メモリリークしているのかを調べるツールが存在します。
詳しくは、「4.参考文献など」の2〜4を参照してください。
■メモリの解放を自動化したい場合は?
C++であればスマートポインタ(※1)を使用するという手があります。
他には、Boehm GCを使用すれば良いらしいですが、詳しいことはだるまは知りません。
詳しくは、「4.参考文献など
」の5,6を参照してください。
-----
※1:たとえば、boost::shared_ptr。
boost::shared_ptrを使用すれば、参照カウント方式でオブジェクトを管理(自動破棄)してくれます。参照カウント方式なので、自己参照や循環参照があると解放されません。そういう場合はboost::weak_ptrも一緒に使いましょう。
VB6.0やVBAではオブジェクトの破棄は自動で行われます。
プログラミングをする上で、どのタイミングでオブジェクトが破棄するのかは理解しておく必要があります。理解していない場合、メモリリークする可能性があります。
■オブジェクトが破棄されるタイミング
参照カウント方式です。オブジェクトへの参照数が0になると、すぐに破棄されます。
そのとき、Terminateイベントが呼び出されます(※1)。
■注意
自己参照や循環参照(※2)があると、オブジェクトが破棄されません。
なぜって、参照数が0にならないから。
-----
※1:
Endステートメントを呼び出すと、参照数が0になってなくても、すべてのオブジェクトが破棄されます。このときはTerminateイベントは呼び出されません。
そもそもEndステートメントはプログラムを終了するためにあるものではありません。Endステートメントはプログラムを終了させるのではなく、強制終了させます。強制終了なので参照数など関係なくすべてのオブジェクトが破棄され、Terminateイベントが呼び出されない仕様となっていると思います。
※2:
クラス図において、双方向関連となっている場合は循環参照になります。
このページはJavaのページではないので、説明はさらっと流す程度にします(※1)。
■特徴
ルート(※2)からたどることのできないオブジェクトは破棄対象のオブジェクトとなります。
なので、参照カウント方式と違い、自己参照や循環参照があっても大丈夫です。
オブジェクトが破棄対象となっても、すぐに破棄されるわけではありません。
-----
※1:
すいません。実は、いろいろ調べました。そしたら、結構難しいのですよ。これが…。
世代別GCについては多少知っていましたが、「強参照」?、「弱参照」?、「ソフト参照」?、「ファントム参照」?知らなかったです。
ちなみに、
Sun認定JavaプログラマではGCのアルゴリズム(Copying GC、世代別GC、コカレントGCなど)や
参照の種類
(弱参照など)は確か試験範囲ではないです。(※ただのいい訳です。)
※2:
具体的にはスタック(スレッドごとにある)(もう少しわかりやすく言うと、現在実行している関数のローカル変数)や静的変数、レジスタ。
このページを作成するのに参考にしたページです。
ただし、だるまが以下のページをちゃんと理解してこのページを作成したとは思わないように。
このページの利用によって発生した、いかなる損害について、このホームページの作成者は責任を負いません。
このページの間違いや嘘を見つけた方、このページに書いて欲しい情報がある方は
メールをお願いします。
Microsoft 、Windows 、Visual Basic および Excel は米国Microsoft
Corporationの米国およびその他の国における登録商標または商標です。
ここではExcel® をエクセル、Visual Basic® for Applications をVBAと表記する場合があります。
Sun、Sun Microsystems、サンのロゴマーク、Java、及び、Sun/Solaris/Java に関連するすべての商標およびロゴマークは米国 Sun Microsystems, Inc. の米国およびその他の国における商標または登録商標です。
Mac 、Mac OS 、Mac OS X は米国Apple Computer,Inc.の登録商標または商標です。
Wikipedia® は Wikimedia Foundation, Inc. の米国およびその他の国における登録商標です。
その他、社名および商品名、システム名称などは、一般に各社の商標または登録商標です。
このホームページの作成者はこれらの会社とはいっさい関係がありません。