バイトの上司に、CとC#は何が違うんだと聞かれました。すごい違います。
といってもCとC#の違いを並べてるサイトなんてたくさんあるので、ここでは主観的なことを交えつつ話をしようと思います。
C#を書いてて思うのは、メモリ管理マジ助かる・ライブラリマジ便利・VisualStudio最高!ってところでしょうか。他にもいろいろありますけど、このへんがC#の最大の利点かな、と思っています。
まぁ、どう考えても長くなるので、CとC#の違い(1)ということで、何回かに分けて書きたいと思います。
ガベージコレクション ~メモリ管理マジ助かる~
C#では、基本的には、使ったメモリを開放する必要はありません。言語側が、使わなくなったメモリを認識し、自動で開放してくれます。
これを、ガベージコレクションといいます。日本語訳すれば、ごみ収集ですね。
メモリの解放なんて、バグの温床だし、めんどくさいです。
その時に必要なのは何と何で…とかちゃんと認識していれば、バグを減らすこともできます。が、そんなのどう考えてもめんどくさい。できるとかできないとかじゃなくて、もうとにかくめんどくさいわけです。freeのfも書きたくない!でもforのfは書きます。
で、
C#は、メモリが足りなくなると、ガベージコレクションが動き出します。オブジェクトが参照されているか。つまりは、手の届くところにあるかどうかが判定され、手の届かないものはどんどん開放されていきます。
手の届かないものは、もう使いようが無いですからね。ゴミなわけです。
あぁ、楽…… 楽です…freeとかdeleteとか自分で書かなくてもいいなんて…
ガベージコレクション自体は、複雑で、重い処理です。
まず、存在するすべてのオブジェクトに対して、生存しているスレッドから間接的にでもアクセスする手段があるかどうかが調べられます。オブジェクトの参照をたどっていって、到達できれば、到達できたよマークが付けられます。(ジェネレーションみたいなのもあるけど、割愛)
そして、到達できなかったオブジェクトに対して、メモリの開放処理を行っていきます。必要があれば、ファイナライズされたりもします。(ファイナライズのへんの処理は複雑なので割愛)
ついでに、メモリの使われなくなった部分が穴あきになりますので、前に詰める処理、コンパクションが行われます。HDDで言うところのデフラグですね。
これで、メモリにはもう必要なオブジェクトしか無く、しかも先頭から綺麗に詰まった状態になりました。
つまり、ガベージコレクションの利点は、メモリの開放が不要になるだけではありません。
新しくメモリを確保するのも、どんどん最後に追加していくだけで良い。Cでは、だんだんメモリが穴あきになっていきますので、空いている十分なスペースを探す必要があります。実はメモリ確保に関しては、CよりもC#のほうが速かったりするんですね。
もちろん、何も考えなきゃ、メモリリークもスタックオーバーフローも、当然起きます。それでもやっぱり、メモリ管理を自分でしなくてもいいのは良いです。精神衛生上、とても良い。
上述しましたが、ガベージコレクションは大変複雑なことをするため、重い処理です。でも、いろんな技術でなるべく効率化されているので、普通に使ってる分には、いつガベージコレクションされたかなんて気づかないでしょう。
もし気になるようであれば、自分でガベージコレクションをスタートさせる事もできます。プログラムなんてほとんどの時間はユーザからの入力待ちです。その時間にこそっとやれば良い。無駄な時間をメモリのために使え、さらにCでメモリ確保にかかっていた時間も節約できて、一石二鳥です。
(手動スタートする場合は、よくガベージコレクションを学んでからのほうがいいです。何も考えなしにやると、逆に遅くなることもあります。)
と、いうことで、CとC#の違い1回目ですが、こんなかんじで。
今日はガベージコレクションの紹介でした。続きはまたいつか。
コンパクションの弊害で、オブジェクトのアドレスが変わってしまったりもする(わざわざポインタ操作しなきゃ気にする必要はない)けど、もうはっきり言ってCとかC++には戻れません。
C#最高!おしまい。