伝説のどいつまの伝説~失敗編~

岩美に永住したい新米エンジニアのあれやこれやな話。

【C#】講義備忘録、其の壱。

メモリ管理

メモリの管理先
主に、スタック・ヒープ・スタティックのどこかに格納される。

スタック
値型がここに格納される。

var a = 1;
var b = 2;
var c = 3;

があったとすると、変数a~cは以下のように格納される。
| 1(a) | 2(b) | 3(c) | .......|
スコープを抜けたら解放される。
スタックのメモリ領域は大きくないから、大きいデータやどれくらい領域を取るかわからないものに関しては向かない。

ヒープ
参照型がここに格納される。
ただし、アドレスはスタックにて管理される。

var a = new int[3] {2, 3, 5};

があったとすると、変数aは以下のように格納される。
スタック領域
| aのアドレス | ...... |
ヒープ領域
| ... | ... | 2 | 3 | 5 | ... |
スコープを抜けたら、ガベージコレクションが任意のタイミングで開放してくれる。

その場で復習として出されたクイズ。

var a = 1;
var b = new int[3] {2, 3, 5};
var c = a;
var d = b;

のような変数a~dがあるとすると、どのようにメモリ確保されているか?
スタック領域
| 1(a) | bのアドレス(b) | 1(c = aのコピー) | bのアドレス(d) | ... |
ヒープ領域
| ... | ... | 2 | 3 | 5 | ... |
aにはそのまま1が格納され、caの値をコピーしているので同じく1を格納。
bは参照型なので、スタック領域にはbのアドレスだけ格納され、ヒープ領域に値が格納される。
c同様、dbのコピーなのでスタック領域にはbのアドレスが格納される。

スタティック
一度データを書き込むとアプリが終了するまでずっとデータを記憶し続ける。


コレクション

配列みたいに複数のデータを扱えるようにしたクラス。
クラスなので、実際の値はヒープ領域に格納される。
Array

配列の作成、操作、検索、および並べ替えを行うメソッドを提供を提供します

Arrayは一度配列の長さを決めたら、Add()メソッドで要素を追加することができない

List

インデックスを使用してアクセスできる、厳密に型指定されたオブジェクトのリストを表します

動的配列とも言われる。Add()メソッドで要素の追加が可能。
この際、実データは新しくメモリ領域を確保し直してデータをコピーし格納している。
以下のようにCapacity()で見てみるとメモリがいつ増えて確保し直しているかとても分かりやすい。

var hoge = new List<int>();
Console.WriteLine("1st : " + hoge.Capacity);
hoge.Add(0);
hoge.Add(1);
hoge.Add(2);
Console.WriteLine("2nd : " + hoge.Capacity);
hoge.Add(3);
hoge.Add(4);
hoge.Add(5);           
hoge.Add(6);
Console.WriteLine("3rd : " + hoge.Capacity);

出力結果
1st : 0
2nd : 4
3rd : 8

LinkedList
双方向リスト。
ArrayやListとは違い、インデックスではなく、個々の要素がノードで格納される。
格納したい値と前後のノードへの参照(PrevNext)をセットで持っている。
要素の挿入・削除は容易だが、先頭から順にアクセスするため

Dictionary<TKey, TValue>
連想配列
Dictionaryの内部では

private struct Entry {
    public int hashCode;
    public int next;
    public TKey key;
    public TValue value;
}

という構造体の配列を保持しているので、オブジェクトの生成は遅い。
しかし、TKeyを格納するときに、ハッシュ値を生成して内部で検索キーとして保持するから検索は早い。


其の壱ってことは、其の弐も勿論あります!w