自動メモリ管理
ガベージコレクション
gcnew 演算子によって生成された参照クラスのインスタンスは delete 演算子を用いて明示的に解放する必要はありません。オブジェクトがコードから参照されなくなった(オブジェクトへのポインタを保持する変数が存在しなくなった)時点で、共通言語ランタイムによって削除されます。このとき発生するオブジェクトの自動解放処理をガベージコレクションと呼びます。
標準 C++ のネイティブ型の場合、new 演算子でインスタンス化したオブジェクトは delete 演算子で解放しなければなりませんでした。例えば、以下のようなコードを実行した場合、delete 演算子でインスタンスを開放していないため、アプリケーションが次々とシステムのメモリリソースを食いつぶします。
class A { int field; }; int main() { while(true) new A(); return 0; }
コード1は while 文で繰り返し A クラスのオブジェクトを生成しています。通常であれば new 演算子が返したオブジェクトへのポインタを受け取り、必要な処理を終えてオブジェクトが不要になった時点で delete 演算子を用いて解放しなければなりませんが、このプログラムでは意図的に行っていません。そのため、アプリケーションが次々と新しいメモリ領域をシステムに要求し、やがては新しいメモリを割り当てられなくなり実行時エラーが発生するでしょう。
一方で、同じようなコードでも参照クラスのオブジェクトであれば自動的に解放されるため、メモリ不足によるエラーが発生することはありません。
ref class A { int field; }; int main() { while(true) gcnew A(); return 0; }
今度はプログラムを実行し続けてもメモリ消費は一定で、アプリケーションがメモリを食いつぶすことはありません。gcnew 演算子で生成した参照クラスのインスタンスは共通言語ランタイムによって管理され、アプリケーションがオブジェクトを指す変数を持たない場合は自動的に解放してくれます。
ただし、このガベージコレクションもメリットばかりではありません。どのタイミングでインスタンスが解放されるかは共通言語ランタイムに委ねられるため、開発者が制御することはできません。ガベージコレクションが発生した瞬間は、メモリ解放の処理が背景で実行されるため、一瞬ではありますが負荷が発生します。一般的なアプリケーションでは問題になることはありませんが、ゲームのような高負荷のリアルタイム処理を行う場合にはガベージコレクションの発生を少なくする工夫が必要になります。