SharpLabを使ったC#のメモリ管理の確認

教科書で、変数には値型と参照型があると学ぶようになりますが、なかなかイメージが掴めないのではないでしょうか
次のようにツールを使って目で確認するのが一番です

値型変数と参照型変数

int a = 3;
Inspect.MemoryGraph(a);

int[] b = new[]{1, 2, 3};
Inspect.MemoryGraph(b);

オブジェクトの変数(参照型)

using System;

Player player1 = new();

Inspect.MemoryGraph(player1);

Console.WriteLine($"{nameof(player1)}変数の内容");
Inspect.Stack(player1);
Console.WriteLine($"{nameof(player1)}のヒープ領域の内容");
Inspect.Heap(player1);
Inspect.Heap(player1.name);

class Player
{
    public string name = "太郎";
    public int age = 10;
}

オブジェクトの変数(内部に参照を持つ場合)

参照型の配列の要素がオブジェクトの場合

using System;

Player[] player = new[] { new Player() { name = "太郎", age = 10 }, new Player() { name = "太郎", age = 10 }, new Player() { name = "三郎", age = 10 }, };
Inspect.MemoryGraph(player);

Console.WriteLine($"{nameof(player)}スタック領域(保存アドレス)");
Inspect.Stack(player);
Console.WriteLine($"\n{nameof(player)}ヒープ領域(データ保存場所)");
Inspect.Heap(player);
Console.WriteLine($"\nplayer[0]ヒープ領域(データ保存場所)");
Inspect.Heap(player[0]);
Console.WriteLine($"player[0].name ヒープ領域(データ保存場所)");
Inspect.Heap(player[0].name);
Console.WriteLine($"\nplayer[1]ヒープ領域(データ保存場所)");
Inspect.Heap(player[1]);
Console.WriteLine($"player[1].name ヒープ領域(データ保存場所)");
Inspect.Heap(player[1].name);
Console.WriteLine($"\nplayer[2]ヒープ領域(データ保存場所)");
Inspect.Heap(player[2]);
Console.WriteLine($"player[2].name ヒープ領域(データ保存場所)");
Inspect.Heap(player[2].name);

class Player
{
    public string name = "太郎";
    public int age = 10;
}

playerヒープ領域(データ保存場所)で、player[0]のアドレスがE0-05-3A-E6-9C-02となっています
これからアドレスを求める場合、逆さまにする必要があります
つまり、02-9C-E6-3A-05-E0となります
同じようにplayer[1]とplayer[2]も変換し、引き算すると、32バイトの差があることがわかります

var x = 0x0600 - 0x05E0;
Console.WriteLine(x);

x = 0x0620 - 0x0600;
Console.WriteLine(x);
32
32

player[0]ヒープ領域(データ保存場所)のサイズをみると、32バイトになります
このことから、player[0]、player[1]、player[2]の実際のデータの格納場所は隣接していることがわかります

C#,学習,設計

Posted by hidepon