2018年06月27日
《その414》ガベージコレクション
ガベージコレクション
std::wstring* p
= new std::wstring(L"あいうえお");
で作成した文字列インスタンスを格納するメモリ領域は、明示的に
delete p;
として解放しない限り、メモリを占有し続けます。
for (int i = 0; i < 5000; i++)
for (int j = 0; j < 5000; j++)
std::wstring* p = new std::wstring(L"あいうえお");
のようなコードでは、メモリの解放をしないまま新しい文字列インスタンスを作り続けているので、メモリ確保に失敗してエラーになる可能性があります。
※メモリ確保に失敗した場合には、例外 bad_alloc が送出されます。
一方、
Platform::String^ s
= ref new Platform::String(L"あいうえお");
のように、ref new を用いて生成された参照クラスのインスタンスでは、不要になった場合にはシステムにより自動的にメモリ解放されます。
したがって、メモリ解放のための明示的なコードを必要としません。
このような、メモリの自動解放の仕組みのことを、ガベージコレクションと呼んでいます。
したがって、
for (int i = 0; i < 5000; i++)
for (int j = 0; j < 5000; j++)
Platform::String^ s
= ref new Platform::String(L"あいうえお");
std::wcout.imbue(std::locale("japanese"));
std::wcout << L"作業完了\n";
の場合には、例外 bad_alloc が送出されることなく、無事に "作業完了" します。
なお、上記の p はポインタと呼ばれるのに対して、上記の s はハンドルと呼ばれることがあります。
ポインタの場合、クラスのメンバにアクセスする際には、例えば、
p->length();
のようにしますが、ハンドルの場合も、同じように、
s->Length();
と書くことができます。
最初のプログラムでは、必要なメモリ解放をしていないため、例外 bad_alloc が送出されます。
#include <iostream>
int main(Platform::Array<Platform::String^>^ args)
{
try {
for (int i = 0; i < 5000; i++)
for (int j = 0; j < 5000; j++)
std::wstring* p
= new std::wstring(L"あいうえお");
std::wcout.imbue(std::locale("japanese"));
std::wcout << L"作業完了\n";
}
catch (std::bad_alloc& e) {
std::cout << e.what() << '\n';
}
}

次のプログラムでは、ガベージコレクションによるメモリの自動解放が行われるため、例外 bad_alloc は送出されません。
#include <iostream>
int main(Platform::Array<Platform::String^>^ args)
{
try {
for (int i = 0; i < 5000; i++)
for (int j = 0; j < 5000; j++)
Platform::String^ s
= ref new Platform::String(L"あいうえお");
std::wcout.imbue(std::locale("japanese"));
std::wcout << L"作業完了\n";
}
catch (std::bad_alloc& e) {
std::cout << e.what() << '\n';
}
}

この記事へのコメント
コメントを書く
この記事へのトラックバックURL
https://fanblogs.jp/tb/7831421
※ブログオーナーが承認したトラックバックのみ表示されます。
この記事へのトラックバック