【ゲーム開発のためのC#入門講座・基礎強化編】ガベージ・コレクションに助けてもらおう【#6】

2022-01-093.0_C#基礎強化編

メモリ管理という悩み

前回の記事にて、第二のメモリ「ヒープメモリ」を活用して参照型がどのように管理されているのかを学びました。ただ、ヒープメモリは万能でなく弱点もありましたね。

そう、メモリのフラグメンテーションメモリリークです。

(忘れてしまった方は下記の記事を見直してみましょう)

このメモリ管理で発生する問題は大昔からプログラマーを悩ませ続けてきました。

特にメモリリークは「解放命令の記述忘れ」なので、プログラマーの完全なミスです。頑張れば防げることなので、往年のプログラマーは皆、「最後に解放するのを絶対に忘れるなよ」と口酸っぱく言われ続けてきたようです。

でも人間がやることですから、やっぱりミスは発生します。また、使い終わったデータをひとつひとつ解放指示するのははっきりいって面倒です。

この問題を何とか出来ないかな、と考えた人が生み出したのがガベージ・コレクションと呼ばれる機能です。

メモリ管理の救世主「ガベージ・コレクション」

ガベージ・コレクションとは、使われていないメモリ領域を探し出して整理してくれる機能のことです。

例えばメモリが下記のような状態だとします。

ヒープメモリがパンクしてしまった!

どうやら新しい参照型のデータを作成しようにも、ヒープメモリの空きが足りなくなってしまったようです。今まで一度も解放命令など出していませんから、どんどん使われなくなったデータが溜まっていってしまったんでしょうね。

このように物理的にメモリが不足している状況に陥ると、ガベージ・コレクションは自動的に発動します。

メモリ不足になると自動発動!
ヒープメモリの使っていないデータを解放
整理されたメモリで処理を継続実行

ガベージ・コレクションが実行されると、ヒープメモリ内にあるデータのうち、どこからも参照されていないデータをまとめて解放してくれます。また、メモリのフラグメンテーションによって歯抜けになった部分も、隙間なく詰め直してくれます。

ようはメモリの自動掃除機能なのです。まさにル○バのような存在ですね。

このガベージ・コレクションがあるため、C#では基本的にプログラマーがメモリの解放命令を出さなくてもよいのです。

これまでstring型や配列を使う際、全くメモリを解放するような命令を出していなくても問題にならなかったのは、この機能のおかげだったんですね。

素晴らしい機能だがこれまた万能ではない

このようにプログラマーの強い味方であるガベージ・コレクションなんですが、やはり万能ではないです。

これはなかなか苦しい話なのですが、実はガベージ・コレクションという存在自体がガベージ・コレクションのデメリットだったりします。

大量の箱、例えば千個の箱についているラベルをすべて張り直す作業を皆さん想像してみてください。一瞬でやる気が吹き飛ぶほどの労力がかかることは容易に想像できますよね。

つまりメモリの一括整理は非常に負荷が高い処理なのです。そのため、 頻繁にヒープメモリが圧迫されるようなプログラムだと高頻度でガベージ・コレクションが発動してしまい、その分処理速度が低下してしまいます。

また、ガベージ・コレクションは自動発動なので、プログラマーからするといつ実行されるのかわかりません。そのため、例えばリアルタイムに精密な動きが要求される場面など、実行して欲しくないタイミングで発動してしまう可能性があるのです。

アクションやシューティングで、ここぞって時にカクカクするようだと、ちょっと困っちゃいますよね。

なので、状況次第ではガベージ・コレクションを手動で実行したり、自分自身でメモリを操作したりした方がよいこともある、ということは頭の片隅にでも覚えておくとよいでしょう。

Unityでの活躍ポイント

デメリットも説明したガベージ・コレクションですが、とはいえ圧倒的にメリットの方が大きいです。ただでさえ未経験者・初心者の方は覚えたばかりのことで頭がいっぱいなのに、メモリのことまで考えてコーディングしなければならないとなったら地獄ですよね。

例えばUnreal EngineやCocos-2xなどのゲーム開発ツールだと、C++という言語で開発を行うことになるのですが、こちらにガベージ・コレクションは実装されていません。自分達でちゃんとメモリのことも考えなきゃいけないんですね(その分自由度は高いですが)。

でもUnityはC#を採用しています。よっぽど処理の重いゲームでない限り、原則メモリ管理のことは考えなくてもOK!

これまでそうしてきたように「どのように使うか」だけ考えて、後片付けはガベージ・コレクションに任せてしまえばよいのです。

大変ありがたいことですね。

スタックメモリの無駄のない運用ルールと、ヒープメモリとガベージ・コレクションの名コンビを頼りにしつつ、こっちは思い通りのゲームを作ることに専念しましょう!

まとめ

  • ガベージ・コレクションとはメモリの自動掃除機能のこと
  • ヒープメモリがいっぱいになると、参照されていないデータをまとめて解放してくれるし、歯抜けも整理してくれる優れもの
  • だからC#では原則プログラマーがメモリ管理を行う必要はない。神!
  • ただしガベージ・コレクション自体は高負荷。いつ実行されるかわからない、頻繁に実行されると処理速度に影響が出る、という点は覚えておこう

今回は知識だけなので演習はありません。

次回は一昔前のネット用語「ぬるぽ」とも関わりの深いnullについて学習します。

それでは、今回もお疲れ様でした!

また次の記事でお会いしましょう!

お借りした素材一覧

この記事では下記サイト様の素材をお借りしています。

ありがとうございました!

かわいいフリー素材集 いらすとや (irasutoya.com)

Posted by 夕目紅