WisdomSoft - for your serial experiences.

自動メモリ管理

参照クラスのインスタンスは共通言語ランタイムによって管理されるため、プログラムから参照されなくなった時点で自動的にメモリから解放してくれます。

ガベージコレクション

gcnew 演算子によって生成された参照クラスのインスタンスは delete 演算子を用いて明示的に解放する必要はありません。オブジェクトがコードから参照されなくなった(オブジェクトへのポインタを保持する変数が存在しなくなった)時点で、共通言語ランタイムによって削除されます。このとき発生するオブジェクトの自動解放処理をガベージコレクションと呼びます。

標準 C++ のネイティブ型の場合、new 演算子でインスタンス化したオブジェクトは delete 演算子で解放しなければなりませんでした。例えば、以下のようなコードを実行した場合、delete 演算子でインスタンスを開放していないため、アプリケーションが次々とシステムのメモリリソースを食いつぶします。

コード1
class A
{
	int field;
};

int main()
{
	while(true) new A();
	return 0;
}
実行結果
コード1 実行結果

コード1は while 文で繰り返し A クラスのオブジェクトを生成しています。通常であれば new 演算子が返したオブジェクトへのポインタを受け取り、必要な処理を終えてオブジェクトが不要になった時点で delete 演算子を用いて解放しなければなりませんが、このプログラムでは意図的に行っていません。そのため、アプリケーションが次々と新しいメモリ領域をシステムに要求し、やがては新しいメモリを割り当てられなくなり実行時エラーが発生するでしょう。

一方で、同じようなコードでも参照クラスのオブジェクトであれば自動的に解放されるため、メモリ不足によるエラーが発生することはありません。

コード2
ref class A
{
	int field;
};

int main()
{
	while(true) gcnew A();
	return 0;
}
実行結果
コード2 実行結果

今度はプログラムを実行し続けてもメモリ消費は一定で、アプリケーションがメモリを食いつぶすことはありません。gcnew 演算子で生成した参照クラスのインスタンスは共通言語ランタイムによって管理され、アプリケーションがオブジェクトを指す変数を持たない場合は自動的に解放してくれます。

ただし、このガベージコレクションもメリットばかりではありません。どのタイミングでインスタンスが解放されるかは共通言語ランタイムに委ねられるため、開発者が制御することはできません。ガベージコレクションが発生した瞬間は、メモリ解放の処理が背景で実行されるため、一瞬ではありますが負荷が発生します。一般的なアプリケーションでは問題になることはありませんが、ゲームのような高負荷のリアルタイム処理を行う場合にはガベージコレクションの発生を少なくする工夫が必要になります。