LoginSignup
16
11

More than 5 years have passed since last update.

【C#】ガベージコレクションについて調べたことまとめ

Posted at

概要

ガベージコレクション周りについて調べたことを忘備録としてまとめておきます。

メモリ領域の種類

プログラム上でメモリを意識する際には、スタック領域とヒープ領域というメモリ領域が存在します。

スタック領域は予め用意されてあるメモリ領域に一時的に保存しておいて、その場ですぐに呼び出す時に使われます。
該当するのは値型と呼ばれるintやfloatなどがこれにあたります。

ヒープ領域はnewなどでインスタンスを生成したときに、新たにメモリ領域を確保して使います。
該当するのは参照型であるクラスや配列、デリゲートがこれに当たります。
また、クラスに入ってる値型もヒープ領域に入ります。

ガベージコレクション

ヒープ領域に確保してあるメモリは確保した分開放しないとそのまま残り続けてどんどん使えるメモリがなくなっていきます。その際に使われなくなったインスタンスを自動でメモリを開放して使えるメモリを確保しようとしてくれるのがガベージコレクションになります。

ガベージコレクションは以下のことをやってくれます。
・使われてないインスタンスの開放

・コンパクション
予め確保したヒープ領域の中にある隙間のメモリ領域を詰めてくれる機能で、メモリの断片化の解決に繋がります。
例としてA,B,Cというメモリを開放した領域があります。新たにDというメモリ領域を確保しようとします。

2018-10-10_01h21_39.png

Bの領域を開放した際にメモリの断片化が起き、Dのメモリ領域の確保はこのままだとできません。

2018-10-10_01h36_57.png

そこでコンパクションをすることによってメモリ領域を詰めることによって断片化が解決し、Dのメモリ領域を確保できるようになりました。

2018-10-10_01h22_46.png

ただ、ガベージコレクションも処理にコストがかかるので、なるべく処理コストを減らすようにするのがベストです。

String

stringは値型のような振る舞いをしていて値型と勘違いしそうですが、実際はクラスです。
=や+、+=は中身を変更しているのではなく実は実行するたびに新しいオブジェクトが生成していて、新しくヒープ領域を確保します。
for文などで何回も文字の連結をやっているとどんどんヒープ領域に溜まっていて、ガベージコレクションをする際に処理を呼び出す時間が増えていきます。
なので、StringBuilderを使って文字を連結するようにするのがベターだと思います。(ケースによってはString.Formatのほうが早いみたいです)

Objectへのボックス化

Object型は何でも入れられる便利な反面、参照型なので扱いに気をつけないといけません。
例えば引数のObjectにintやfloatなど値型を渡すと、参照型であるObjectに変換されてしまいます。
これをボックス化といいます。
ボックス化は本来スタック領域に保存されるはずだったメモリがヒープ領域にメモリが確保されてしまいます。
なのでできるだけObject型を使わずに型が決まってるものは指定してあげるのがベストです。

参考

++C++; // 未確認飛行 C メモリ管理

16
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
11